app.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. require('./polyfill');
  2. window._ = require('lodash');
  3. window.Popper = require('popper.js').default;
  4. window.pixelfed = window.pixelfed || {};
  5. window.$ = window.jQuery = require('jquery');
  6. require('bootstrap');
  7. window.axios = require('axios');
  8. window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
  9. require('readmore-js');
  10. window.blurhash = require("blurhash");
  11. let token = document.head.querySelector('meta[name="csrf-token"]');
  12. if (token) {
  13. window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
  14. } else {
  15. console.error('CSRF token not found.');
  16. }
  17. window.App = window.App || {};
  18. window.App.redirect = function() {
  19. document.querySelectorAll('a').forEach(function(i,k) {
  20. let a = i.getAttribute('href');
  21. if(a && a.length > 5 && a.startsWith('https://')) {
  22. let url = new URL(a);
  23. if(url.host !== window.location.host && url.pathname !== '/i/redirect') {
  24. i.setAttribute('href', '/i/redirect?url=' + encodeURIComponent(a));
  25. }
  26. }
  27. });
  28. }
  29. window.App.boot = function() {
  30. new Vue({ el: '#content'});
  31. }
  32. window.addEventListener("load", () => {
  33. if ("serviceWorker" in navigator) {
  34. navigator.serviceWorker.register("/sw.js");
  35. }
  36. });
  37. window.App.util = {
  38. compose: {
  39. post: (function() {
  40. let path = window.location.pathname;
  41. let whitelist = [
  42. '/',
  43. '/timeline/public'
  44. ];
  45. if(whitelist.includes(path)) {
  46. $('#composeModal').modal('show');
  47. } else {
  48. window.location.href = '/?a=co';
  49. }
  50. }),
  51. circle: (function() {
  52. console.log('Unsupported method.');
  53. }),
  54. collection: (function() {
  55. console.log('Unsupported method.');
  56. }),
  57. loop: (function() {
  58. console.log('Unsupported method.');
  59. }),
  60. story: (function() {
  61. console.log('Unsupported method.');
  62. }),
  63. },
  64. time: (function() {
  65. return new Date;
  66. }),
  67. version: 1,
  68. format: {
  69. count: (function(count = 0, locale = 'en-GB', notation = 'compact') {
  70. if(count < 1) {
  71. return 0;
  72. }
  73. return new Intl.NumberFormat(locale, { notation: notation , compactDisplay: "short" }).format(count);
  74. }),
  75. timeAgo: (function(ts) {
  76. let date = Date.parse(ts);
  77. let seconds = Math.floor((new Date() - date) / 1000);
  78. let interval = Math.floor(seconds / 63072000);
  79. if (interval >= 1) {
  80. return interval + "y";
  81. }
  82. interval = Math.floor(seconds / 604800);
  83. if (interval >= 1) {
  84. return interval + "w";
  85. }
  86. interval = Math.floor(seconds / 86400);
  87. if (interval >= 1) {
  88. return interval + "d";
  89. }
  90. interval = Math.floor(seconds / 3600);
  91. if (interval >= 1) {
  92. return interval + "h";
  93. }
  94. interval = Math.floor(seconds / 60);
  95. if (interval >= 1) {
  96. return interval + "m";
  97. }
  98. return Math.floor(seconds) + "s";
  99. }),
  100. timeAhead: (function(ts, short = true) {
  101. let date = Date.parse(ts);
  102. let diff = date - Date.parse(new Date());
  103. let seconds = Math.floor((diff) / 1000);
  104. let interval = Math.floor(seconds / 63072000);
  105. if (interval >= 1) {
  106. return interval + (short ? "y" : " years");
  107. }
  108. interval = Math.floor(seconds / 604800);
  109. if (interval >= 1) {
  110. return interval + (short ? "w" : " weeks");
  111. }
  112. interval = Math.floor(seconds / 86400);
  113. if (interval >= 1) {
  114. return interval + (short ? "d" : " days");
  115. }
  116. interval = Math.floor(seconds / 3600);
  117. if (interval >= 1) {
  118. return interval + (short ? "h" : " hours");
  119. }
  120. interval = Math.floor(seconds / 60);
  121. if (interval >= 1) {
  122. return interval + (short ? "m" : " minutes");
  123. }
  124. return Math.floor(seconds) + (short ? "s" : " seconds");
  125. }),
  126. rewriteLinks: (function(i) {
  127. let tag = i.innerText;
  128. if(i.href.startsWith(window.location.origin)) {
  129. return i.href;
  130. }
  131. if(tag.startsWith('#') == true) {
  132. tag = '/discover/tags/' + tag.substr(1) +'?src=rph';
  133. } else if(tag.startsWith('@') == true) {
  134. tag = '/' + i.innerText + '?src=rpp';
  135. } else {
  136. tag = '/i/redirect?url=' + encodeURIComponent(tag);
  137. }
  138. return tag;
  139. })
  140. },
  141. filters: [
  142. ['1977','filter-1977'],
  143. ['Aden','filter-aden'],
  144. ['Amaro','filter-amaro'],
  145. ['Ashby','filter-ashby'],
  146. ['Brannan','filter-brannan'],
  147. ['Brooklyn','filter-brooklyn'],
  148. ['Charmes','filter-charmes'],
  149. ['Clarendon','filter-clarendon'],
  150. ['Crema','filter-crema'],
  151. ['Dogpatch','filter-dogpatch'],
  152. ['Earlybird','filter-earlybird'],
  153. ['Gingham','filter-gingham'],
  154. ['Ginza','filter-ginza'],
  155. ['Hefe','filter-hefe'],
  156. ['Helena','filter-helena'],
  157. ['Hudson','filter-hudson'],
  158. ['Inkwell','filter-inkwell'],
  159. ['Kelvin','filter-kelvin'],
  160. ['Kuno','filter-juno'],
  161. ['Lark','filter-lark'],
  162. ['Lo-Fi','filter-lofi'],
  163. ['Ludwig','filter-ludwig'],
  164. ['Maven','filter-maven'],
  165. ['Mayfair','filter-mayfair'],
  166. ['Moon','filter-moon'],
  167. ['Nashville','filter-nashville'],
  168. ['Perpetua','filter-perpetua'],
  169. ['Poprocket','filter-poprocket'],
  170. ['Reyes','filter-reyes'],
  171. ['Rise','filter-rise'],
  172. ['Sierra','filter-sierra'],
  173. ['Skyline','filter-skyline'],
  174. ['Slumber','filter-slumber'],
  175. ['Stinson','filter-stinson'],
  176. ['Sutro','filter-sutro'],
  177. ['Toaster','filter-toaster'],
  178. ['Valencia','filter-valencia'],
  179. ['Vesper','filter-vesper'],
  180. ['Walden','filter-walden'],
  181. ['Willow','filter-willow'],
  182. ['X-Pro II','filter-xpro-ii']
  183. ],
  184. filterCss: {
  185. 'filter-1977': 'sepia(.5) hue-rotate(-30deg) saturate(1.4)',
  186. 'filter-aden': 'sepia(.2) brightness(1.15) saturate(1.4)',
  187. 'filter-amaro': 'sepia(.35) contrast(1.1) brightness(1.2) saturate(1.3)',
  188. 'filter-ashby': 'sepia(.5) contrast(1.2) saturate(1.8)',
  189. 'filter-brannan': 'sepia(.4) contrast(1.25) brightness(1.1) saturate(.9) hue-rotate(-2deg)',
  190. 'filter-brooklyn': 'sepia(.25) contrast(1.25) brightness(1.25) hue-rotate(5deg)',
  191. 'filter-charmes': 'sepia(.25) contrast(1.25) brightness(1.25) saturate(1.35) hue-rotate(-5deg)',
  192. 'filter-clarendon': 'sepia(.15) contrast(1.25) brightness(1.25) hue-rotate(5deg)',
  193. 'filter-crema': 'sepia(.5) contrast(1.25) brightness(1.15) saturate(.9) hue-rotate(-2deg)',
  194. 'filter-dogpatch': 'sepia(.35) saturate(1.1) contrast(1.5)',
  195. 'filter-earlybird': 'sepia(.25) contrast(1.25) brightness(1.15) saturate(.9) hue-rotate(-5deg)',
  196. 'filter-gingham': 'contrast(1.1) brightness(1.1)',
  197. 'filter-ginza': 'sepia(.25) contrast(1.15) brightness(1.2) saturate(1.35) hue-rotate(-5deg)',
  198. 'filter-hefe': 'sepia(.4) contrast(1.5) brightness(1.2) saturate(1.4) hue-rotate(-10deg)',
  199. 'filter-helena': 'sepia(.5) contrast(1.05) brightness(1.05) saturate(1.35)',
  200. 'filter-hudson': 'sepia(.25) contrast(1.2) brightness(1.2) saturate(1.05) hue-rotate(-15deg)',
  201. 'filter-inkwell': 'brightness(1.25) contrast(.85) grayscale(1)',
  202. 'filter-kelvin': 'sepia(.15) contrast(1.5) brightness(1.1) hue-rotate(-10deg)',
  203. 'filter-juno': 'sepia(.35) contrast(1.15) brightness(1.15) saturate(1.8)',
  204. 'filter-lark': 'sepia(.25) contrast(1.2) brightness(1.3) saturate(1.25)',
  205. 'filter-lofi': 'saturate(1.1) contrast(1.5)',
  206. 'filter-ludwig': 'sepia(.25) contrast(1.05) brightness(1.05) saturate(2)',
  207. 'filter-maven': 'sepia(.35) contrast(1.05) brightness(1.05) saturate(1.75)',
  208. 'filter-mayfair': 'contrast(1.1) brightness(1.15) saturate(1.1)',
  209. 'filter-moon': 'brightness(1.4) contrast(.95) saturate(0) sepia(.35)',
  210. 'filter-nashville': 'sepia(.25) contrast(1.5) brightness(.9) hue-rotate(-15deg)',
  211. 'filter-perpetua': 'contrast(1.1) brightness(1.25) saturate(1.1)',
  212. 'filter-poprocket': 'sepia(.15) brightness(1.2)',
  213. 'filter-reyes': 'sepia(.75) contrast(.75) brightness(1.25) saturate(1.4)',
  214. 'filter-rise': 'sepia(.25) contrast(1.25) brightness(1.2) saturate(.9)',
  215. 'filter-sierra': 'sepia(.25) contrast(1.5) brightness(.9) hue-rotate(-15deg)',
  216. 'filter-skyline': 'sepia(.15) contrast(1.25) brightness(1.25) saturate(1.2)',
  217. 'filter-slumber': 'sepia(.35) contrast(1.25) saturate(1.25)',
  218. 'filter-stinson': 'sepia(.35) contrast(1.25) brightness(1.1) saturate(1.25)',
  219. 'filter-sutro': 'sepia(.4) contrast(1.2) brightness(.9) saturate(1.4) hue-rotate(-10deg)',
  220. 'filter-toaster': 'sepia(.25) contrast(1.5) brightness(.95) hue-rotate(-15deg)',
  221. 'filter-valencia': 'sepia(.25) contrast(1.1) brightness(1.1)',
  222. 'filter-vesper': 'sepia(.35) contrast(1.15) brightness(1.2) saturate(1.3)',
  223. 'filter-walden': 'sepia(.35) contrast(.8) brightness(1.25) saturate(1.4)',
  224. 'filter-willow': 'brightness(1.2) contrast(.85) saturate(.05) sepia(.2)',
  225. 'filter-xpro-ii': 'sepia(.45) contrast(1.25) brightness(1.75) saturate(1.3) hue-rotate(-5deg)'
  226. },
  227. emoji: [
  228. '😂','💯','❤️','🙌','👏','👌','😍','😯','😢','😅','😁','🙂','😎','😀','🤣','😃','😄','😆','😉','😊','😋','😘','😗','😙','😚','🤗','🤩','🤔','🤨','😐','😑','😶','🙄','😏','😣','😥','😮','🤐','😪','😫','😴','😌','😛','😜','😝','🤤','😒','😓','😔','😕','🙃','🤑','😲','🙁','😖','😞','😟','😤','😭','😦','😧','😨','😩','🤯','😬','😰','😱','😳','🤪','😵','😡','😠','🤬','😷','🤒','🤕','🤢','🤮','🤧','😇','🤠','🤡','🤥','🤫','🤭','🧐','🤓','😈','👿','👹','👺','💀','👻','👽','🤖','💩','😺','😸','😹','😻','😼','😽','🙀','😿','😾','🤲','👐','🤝','👍','👎','👊','✊','🤛','🤜','🤞','✌️','🤟','🤘','👈','👉','👆','👇','☝️','✋','🤚','🖐','🖖','👋','🤙','💪','🖕','✍️','🙏','💍','💄','💋','👄','👅','👂','👃','👣','👁','👀','🧠','🗣','👤','👥'
  229. ],
  230. embed: {
  231. post: (function(url, caption = true, likes = false, layout = 'full') {
  232. let u = url + '/embed?';
  233. u += caption ? 'caption=true&' : 'caption=false&';
  234. u += likes ? 'likes=true&' : 'likes=false&';
  235. u += layout == 'compact' ? 'layout=compact' : 'layout=full';
  236. return '<iframe src="'+u+'" class="pixelfed__embed" style="max-width: 100%; border: 0" width="400" allowfullscreen="allowfullscreen"></iframe><script async defer src="'+window.location.origin +'/embed.js"><\/script>';
  237. }),
  238. profile: (function(url) {
  239. let u = url + '/embed';
  240. return '<iframe src="'+u+'" class="pixelfed__embed" style="max-width: 100%; border: 0" width="400" allowfullscreen="allowfullscreen"></iframe><script async defer src="'+window.location.origin +'/embed.js"><\/script>';
  241. })
  242. },
  243. clipboard: (function(data) {
  244. return navigator.clipboard.writeText(data);
  245. }),
  246. navatar: (function() {
  247. $('#navbarDropdown .far').addClass('d-none');
  248. $('#navbarDropdown img').attr('src',window._sharedData.curUser.avatar)
  249. .removeClass('d-none')
  250. .addClass('rounded-circle border shadow')
  251. .attr('width', 38).attr('height', 38);
  252. })
  253. };