app.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. import VueI18n from 'vue-i18n';
  2. require('./polyfill');
  3. window._ = require('lodash');
  4. window.Popper = require('popper.js').default;
  5. window.pixelfed = window.pixelfed || {};
  6. window.$ = window.jQuery = require('jquery');
  7. require('bootstrap');
  8. window.axios = require('axios');
  9. window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
  10. require('readmore-js');
  11. window.blurhash = require("blurhash");
  12. let token = document.head.querySelector('meta[name="csrf-token"]');
  13. if (token) {
  14. window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
  15. } else {
  16. console.error('CSRF token not found.');
  17. }
  18. window.App = window.App || {};
  19. window.App.redirect = function() {
  20. document.querySelectorAll('a').forEach(function(i,k) {
  21. let a = i.getAttribute('href');
  22. if(a && a.length > 5 && a.startsWith('https://')) {
  23. let url = new URL(a);
  24. if(url.host !== window.location.host && url.pathname !== '/i/redirect') {
  25. i.setAttribute('href', '/i/redirect?url=' + encodeURIComponent(a));
  26. }
  27. }
  28. });
  29. }
  30. window.App.boot = function() {
  31. Vue.use(VueI18n);
  32. let i18nMessages = {
  33. en: require('./i18n/en.json'),
  34. pt: require('./i18n/pt.json'),
  35. };
  36. let locale = document.querySelector('html').getAttribute('lang');
  37. const i18n = new VueI18n({
  38. locale: locale, // set locale
  39. fallbackLocale: 'en',
  40. messages: i18nMessages
  41. });
  42. new Vue({
  43. el: '#content',
  44. i18n,
  45. });
  46. }
  47. window.addEventListener("load", () => {
  48. if ("serviceWorker" in navigator) {
  49. navigator.serviceWorker.register("/sw.js");
  50. }
  51. });
  52. window.App.util = {
  53. compose: {
  54. post: (function() {
  55. let path = window.location.pathname;
  56. let whitelist = [
  57. '/',
  58. '/timeline/public'
  59. ];
  60. if(whitelist.includes(path)) {
  61. $('#composeModal').modal('show');
  62. } else {
  63. window.location.href = '/?a=co';
  64. }
  65. }),
  66. circle: (function() {
  67. console.log('Unsupported method.');
  68. }),
  69. collection: (function() {
  70. console.log('Unsupported method.');
  71. }),
  72. loop: (function() {
  73. console.log('Unsupported method.');
  74. }),
  75. story: (function() {
  76. console.log('Unsupported method.');
  77. }),
  78. },
  79. time: (function() {
  80. return new Date;
  81. }),
  82. version: 1,
  83. format: {
  84. count: (function(count = 0, locale = 'en-GB', notation = 'compact') {
  85. if(count < 1) {
  86. return 0;
  87. }
  88. return new Intl.NumberFormat(locale, { notation: notation , compactDisplay: "short" }).format(count);
  89. }),
  90. timeAgo: (function(ts) {
  91. const date = new Date(ts);
  92. const now = new Date();
  93. const seconds = Math.floor((now - date) / 1000);
  94. const secondsInYear = 60 * 60 * 24 * 365.25;
  95. let interval = Math.floor(seconds / secondsInYear);
  96. if (interval >= 1) {
  97. return interval + "y";
  98. }
  99. interval = Math.floor(seconds / (60 * 60 * 24 * 7));
  100. if (interval >= 1) {
  101. return interval + "w";
  102. }
  103. interval = Math.floor(seconds / (60 * 60 * 24));
  104. if (interval >= 1) {
  105. return interval + "d";
  106. }
  107. interval = Math.floor(seconds / (60 * 60));
  108. if (interval >= 1) {
  109. return interval + "h";
  110. }
  111. interval = Math.floor(seconds / 60);
  112. if (interval >= 1) {
  113. return interval + "m";
  114. }
  115. return Math.floor(seconds) + "s";
  116. }),
  117. timeAhead: (function(ts, short = true) {
  118. let date = Date.parse(ts);
  119. let diff = date - Date.parse(new Date());
  120. let seconds = Math.floor((diff) / 1000);
  121. let interval = Math.floor(seconds / 63072000);
  122. if (interval >= 1) {
  123. return interval + (short ? "y" : " years");
  124. }
  125. interval = Math.floor(seconds / 604800);
  126. if (interval >= 1) {
  127. return interval + (short ? "w" : " weeks");
  128. }
  129. interval = Math.floor(seconds / 86400);
  130. if (interval >= 1) {
  131. return interval + (short ? "d" : " days");
  132. }
  133. interval = Math.floor(seconds / 3600);
  134. if (interval >= 1) {
  135. return interval + (short ? "h" : " hours");
  136. }
  137. interval = Math.floor(seconds / 60);
  138. if (interval >= 1) {
  139. return interval + (short ? "m" : " minutes");
  140. }
  141. return Math.floor(seconds) + (short ? "s" : " seconds");
  142. }),
  143. rewriteLinks: (function(i) {
  144. let tag = i.innerText;
  145. if(i.href.startsWith(window.location.origin)) {
  146. return i.href;
  147. }
  148. if(tag.startsWith('#') == true) {
  149. tag = '/discover/tags/' + tag.substr(1) +'?src=rph';
  150. } else if(tag.startsWith('@') == true) {
  151. tag = '/' + i.innerText + '?src=rpp';
  152. } else {
  153. tag = '/i/redirect?url=' + encodeURIComponent(tag);
  154. }
  155. return tag;
  156. })
  157. },
  158. filters: [
  159. ['1984','filter-1977'],
  160. ['Azen','filter-aden'],
  161. ['Astairo','filter-amaro'],
  162. ['Grassbee','filter-ashby'],
  163. ['Bookrun','filter-brannan'],
  164. ['Borough','filter-brooklyn'],
  165. ['Farms','filter-charmes'],
  166. ['Hairsadone','filter-clarendon'],
  167. ['Cleana ','filter-crema'],
  168. ['Catpatch','filter-dogpatch'],
  169. ['Earlyworm','filter-earlybird'],
  170. ['Plaid','filter-gingham'],
  171. ['Kyo','filter-ginza'],
  172. ['Yefe','filter-hefe'],
  173. ['Goddess','filter-helena'],
  174. ['Yards','filter-hudson'],
  175. ['Quill','filter-inkwell'],
  176. ['Rankine','filter-kelvin'],
  177. ['Juno','filter-juno'],
  178. ['Mark','filter-lark'],
  179. ['Chill','filter-lofi'],
  180. ['Van','filter-ludwig'],
  181. ['Apache','filter-maven'],
  182. ['May','filter-mayfair'],
  183. ['Ceres','filter-moon'],
  184. ['Knoxville','filter-nashville'],
  185. ['Felicity','filter-perpetua'],
  186. ['Sandblast','filter-poprocket'],
  187. ['Daisy','filter-reyes'],
  188. ['Elevate','filter-rise'],
  189. ['Nevada','filter-sierra'],
  190. ['Futura','filter-skyline'],
  191. ['Sleepy','filter-slumber'],
  192. ['Steward','filter-stinson'],
  193. ['Savoy','filter-sutro'],
  194. ['Blaze','filter-toaster'],
  195. ['Apricot','filter-valencia'],
  196. ['Gloming','filter-vesper'],
  197. ['Walter','filter-walden'],
  198. ['Poplar','filter-willow'],
  199. ['Xenon','filter-xpro-ii']
  200. ],
  201. filterCss: {
  202. 'filter-1977': 'sepia(.5) hue-rotate(-30deg) saturate(1.4)',
  203. 'filter-aden': 'sepia(.2) brightness(1.15) saturate(1.4)',
  204. 'filter-amaro': 'sepia(.35) contrast(1.1) brightness(1.2) saturate(1.3)',
  205. 'filter-ashby': 'sepia(.5) contrast(1.2) saturate(1.8)',
  206. 'filter-brannan': 'sepia(.4) contrast(1.25) brightness(1.1) saturate(.9) hue-rotate(-2deg)',
  207. 'filter-brooklyn': 'sepia(.25) contrast(1.25) brightness(1.25) hue-rotate(5deg)',
  208. 'filter-charmes': 'sepia(.25) contrast(1.25) brightness(1.25) saturate(1.35) hue-rotate(-5deg)',
  209. 'filter-clarendon': 'sepia(.15) contrast(1.25) brightness(1.25) hue-rotate(5deg)',
  210. 'filter-crema': 'sepia(.5) contrast(1.25) brightness(1.15) saturate(.9) hue-rotate(-2deg)',
  211. 'filter-dogpatch': 'sepia(.35) saturate(1.1) contrast(1.5)',
  212. 'filter-earlybird': 'sepia(.25) contrast(1.25) brightness(1.15) saturate(.9) hue-rotate(-5deg)',
  213. 'filter-gingham': 'contrast(1.1) brightness(1.1)',
  214. 'filter-ginza': 'sepia(.25) contrast(1.15) brightness(1.2) saturate(1.35) hue-rotate(-5deg)',
  215. 'filter-hefe': 'sepia(.4) contrast(1.5) brightness(1.2) saturate(1.4) hue-rotate(-10deg)',
  216. 'filter-helena': 'sepia(.5) contrast(1.05) brightness(1.05) saturate(1.35)',
  217. 'filter-hudson': 'sepia(.25) contrast(1.2) brightness(1.2) saturate(1.05) hue-rotate(-15deg)',
  218. 'filter-inkwell': 'brightness(1.25) contrast(.85) grayscale(1)',
  219. 'filter-kelvin': 'sepia(.15) contrast(1.5) brightness(1.1) hue-rotate(-10deg)',
  220. 'filter-juno': 'sepia(.35) contrast(1.15) brightness(1.15) saturate(1.8)',
  221. 'filter-lark': 'sepia(.25) contrast(1.2) brightness(1.3) saturate(1.25)',
  222. 'filter-lofi': 'saturate(1.1) contrast(1.5)',
  223. 'filter-ludwig': 'sepia(.25) contrast(1.05) brightness(1.05) saturate(2)',
  224. 'filter-maven': 'sepia(.35) contrast(1.05) brightness(1.05) saturate(1.75)',
  225. 'filter-mayfair': 'contrast(1.1) brightness(1.15) saturate(1.1)',
  226. 'filter-moon': 'brightness(1.4) contrast(.95) saturate(0) sepia(.35)',
  227. 'filter-nashville': 'sepia(.25) contrast(1.5) brightness(.9) hue-rotate(-15deg)',
  228. 'filter-perpetua': 'contrast(1.1) brightness(1.25) saturate(1.1)',
  229. 'filter-poprocket': 'sepia(.15) brightness(1.2)',
  230. 'filter-reyes': 'sepia(.75) contrast(.75) brightness(1.25) saturate(1.4)',
  231. 'filter-rise': 'sepia(.25) contrast(1.25) brightness(1.2) saturate(.9)',
  232. 'filter-sierra': 'sepia(.25) contrast(1.5) brightness(.9) hue-rotate(-15deg)',
  233. 'filter-skyline': 'sepia(.15) contrast(1.25) brightness(1.25) saturate(1.2)',
  234. 'filter-slumber': 'sepia(.35) contrast(1.25) saturate(1.25)',
  235. 'filter-stinson': 'sepia(.35) contrast(1.25) brightness(1.1) saturate(1.25)',
  236. 'filter-sutro': 'sepia(.4) contrast(1.2) brightness(.9) saturate(1.4) hue-rotate(-10deg)',
  237. 'filter-toaster': 'sepia(.25) contrast(1.5) brightness(.95) hue-rotate(-15deg)',
  238. 'filter-valencia': 'sepia(.25) contrast(1.1) brightness(1.1)',
  239. 'filter-vesper': 'sepia(.35) contrast(1.15) brightness(1.2) saturate(1.3)',
  240. 'filter-walden': 'sepia(.35) contrast(.8) brightness(1.25) saturate(1.4)',
  241. 'filter-willow': 'brightness(1.2) contrast(.85) saturate(.05) sepia(.2)',
  242. 'filter-xpro-ii': 'sepia(.45) contrast(1.25) brightness(1.75) saturate(1.3) hue-rotate(-5deg)'
  243. },
  244. emoji: [
  245. '๐Ÿ˜‚','๐Ÿ’ฏ','โค๏ธ','๐Ÿ™Œ','๐Ÿ‘','๐Ÿ‘Œ','๐Ÿ˜','๐Ÿ˜ฏ','๐Ÿ˜ข','๐Ÿ˜…','๐Ÿ˜','๐Ÿ™‚','๐Ÿ˜Ž','๐Ÿ˜€','๐Ÿคฃ','๐Ÿ˜ƒ','๐Ÿ˜„','๐Ÿ˜†','๐Ÿ˜‰','๐Ÿ˜Š','๐Ÿ˜‹','๐Ÿ˜˜','๐Ÿ˜—','๐Ÿ˜™','๐Ÿ˜š','๐Ÿค—','๐Ÿคฉ','๐Ÿค”','๐Ÿคจ','๐Ÿ˜','๐Ÿ˜‘','๐Ÿ˜ถ','๐Ÿ™„','๐Ÿ˜','๐Ÿ˜ฃ','๐Ÿ˜ฅ','๐Ÿ˜ฎ','๐Ÿค','๐Ÿ˜ช','๐Ÿ˜ซ','๐Ÿ˜ด','๐Ÿ˜Œ','๐Ÿ˜›','๐Ÿ˜œ','๐Ÿ˜','๐Ÿคค','๐Ÿ˜’','๐Ÿ˜“','๐Ÿ˜”','๐Ÿ˜•','๐Ÿ™ƒ','๐Ÿค‘','๐Ÿ˜ฒ','๐Ÿ™','๐Ÿ˜–','๐Ÿ˜ž','๐Ÿ˜Ÿ','๐Ÿ˜ค','๐Ÿ˜ญ','๐Ÿ˜ฆ','๐Ÿ˜ง','๐Ÿ˜จ','๐Ÿ˜ฉ','๐Ÿคฏ','๐Ÿ˜ฌ','๐Ÿ˜ฐ','๐Ÿ˜ฑ','๐Ÿ˜ณ','๐Ÿคช','๐Ÿ˜ต','๐Ÿ˜ก','๐Ÿ˜ ','๐Ÿคฌ','๐Ÿ˜ท','๐Ÿค’','๐Ÿค•','๐Ÿคข','๐Ÿคฎ','๐Ÿคง','๐Ÿ˜‡','๐Ÿค ','๐Ÿคก','๐Ÿคฅ','๐Ÿคซ','๐Ÿคญ','๐Ÿง','๐Ÿค“','๐Ÿ˜ˆ','๐Ÿ‘ฟ','๐Ÿ‘น','๐Ÿ‘บ','๐Ÿ’€','๐Ÿ‘ป','๐Ÿ‘ฝ','๐Ÿค–','๐Ÿ’ฉ','๐Ÿ˜บ','๐Ÿ˜ธ','๐Ÿ˜น','๐Ÿ˜ป','๐Ÿ˜ผ','๐Ÿ˜ฝ','๐Ÿ™€','๐Ÿ˜ฟ','๐Ÿ˜พ','๐Ÿคฒ','๐Ÿ‘','๐Ÿค','๐Ÿ‘','๐Ÿ‘Ž','๐Ÿ‘Š','โœŠ','๐Ÿค›','๐Ÿคœ','๐Ÿคž','โœŒ๏ธ','๐ŸคŸ','๐Ÿค˜','๐Ÿ‘ˆ','๐Ÿ‘‰','๐Ÿ‘†','๐Ÿ‘‡','โ˜๏ธ','โœ‹','๐Ÿคš','๐Ÿ–','๐Ÿ––','๐Ÿ‘‹','๐Ÿค™','๐Ÿ’ช','๐Ÿ–•','โœ๏ธ','๐Ÿ™','๐Ÿ’','๐Ÿ’„','๐Ÿ’‹','๐Ÿ‘„','๐Ÿ‘…','๐Ÿ‘‚','๐Ÿ‘ƒ','๐Ÿ‘ฃ','๐Ÿ‘','๐Ÿ‘€','๐Ÿง ','๐Ÿ—ฃ','๐Ÿ‘ค','๐Ÿ‘ฅ'
  246. ],
  247. embed: {
  248. post: (function(url, caption = true, likes = false, layout = 'full') {
  249. let u = url + '/embed?';
  250. u += caption ? 'caption=true&' : 'caption=false&';
  251. u += likes ? 'likes=true&' : 'likes=false&';
  252. u += layout == 'compact' ? 'layout=compact' : 'layout=full';
  253. return '<iframe title="Pixelfed Post Embed" 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>';
  254. }),
  255. profile: (function(url) {
  256. let u = url + '/embed';
  257. return '<iframe title="Pixelfed Profile Embed" 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>';
  258. })
  259. },
  260. clipboard: (function(data) {
  261. return navigator.clipboard.writeText(data);
  262. }),
  263. navatar: (function() {
  264. $('#navbarDropdown .far').addClass('d-none');
  265. $('#navbarDropdown img').attr('src',window._sharedData.curUser.avatar)
  266. .removeClass('d-none')
  267. .addClass('rounded-circle border shadow')
  268. .attr('width', 38).attr('height', 38);
  269. })
  270. };