1
0

My2020.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <template>
  2. <div class="bg-dark text-white">
  3. <div v-if="!loaded" style="height: 100vh;" class="d-flex justify-content-center align-items-center">
  4. <div class="text-center">
  5. <div class="spinner-border text-light" role="status">
  6. <span class="sr-only">Loading...</span>
  7. </div>
  8. <p class="mb-0 lead mt-2">Loading</p>
  9. </div>
  10. </div>
  11. <div v-if="loaded && notEnoughData" style="height: 100vh;" class="d-flex justify-content-center align-items-center">
  12. <div class="text-center">
  13. <p class="display-4">Oops!</p>
  14. <p class="h3 font-weight-light py-3">We don't have enough data to display your <span class="font-weight-bold">#my2020</span>.</p>
  15. <p class="mb-0 h5 font-weight-light">We hope to see you next year!</p>
  16. </div>
  17. </div>
  18. <div v-if="loaded && !notEnoughData" class="d-flex justify-content-center align-items-center" style="width:100%;height:100vh;min-height:500px; padding: 0 15px;">
  19. <div v-if="page == 1" class="text-center">
  20. <p class="h1 font-weight-light">Hello {{user.username}}!</p>
  21. <p class="h1 py-4">Your 2020 on Pixelfed.</p>
  22. <p class="h4 font-weight-light mb-0 animate__animated animate__bounceInDown">Use the buttons below to navigate.</p>
  23. </div>
  24. <div v-if="page == 2" class="text-center mw-500">
  25. <p class="display-4">User #<span class="font-weight-bold">{{stats.account.user_id}}</span></p>
  26. <p class="h3 font-weight-light mb-0">You joined Pixelfed on {{stats.account.created_at}}</p>
  27. </div>
  28. <div v-if="page == 3" class="text-center mw-500">
  29. <p class="display-4">You created <span class="font-weight-bold">{{stats.account.posts_count}}</span> posts</p>
  30. <p class="h3 font-weight-light mb-0">The average user created <span class="font-weight-bold">{{stats.average.posts}}</span> posts this year.</p>
  31. </div>
  32. <div v-if="page == 4" class="text-center mw-500">
  33. <p class="display-4">You liked <span class="font-weight-bold">{{stats.account.likes_count}}</span> posts</p>
  34. <p class="h3 font-weight-light mb-0">The average user liked <span class="font-weight-bold">{{stats.average.likes}}</span> posts this year.</p>
  35. </div>
  36. <div v-if="page == 5" class="text-center mw-500">
  37. <div v-if="stats.account.most_popular">
  38. <p class="h1 font-weight-light mb-0 text-break md-line-height">Your most popular post of 2020 was created on <span class="font-weight-bold">{{stats.account.most_popular.created_at}}</span> with <span class="font-weight-bold">{{stats.account.most_popular.likes_count}}</span> likes.</p>
  39. <p class="mt-4 mb-0">
  40. <a class="btn btn-outline-light btn-lg btn-block rounded-pill" :href="stats.account.most_popular.url">View Post</a>
  41. </p>
  42. </div>
  43. <div v-else>
  44. <p class="h1 font-weight-light mb-0 text-break md-line-height">The most popular post of 2020 was created by <span class="font-weight-bold">{{stats.popular.post.username}}</span> on <span class="font-weight-bold">{{stats.popular.post.created_at}}</span> with <span class="font-weight-bold">{{stats.popular.post.likes_count}}</span> likes.</p>
  45. <p class="mt-4 mb-0">
  46. <a class="btn btn-outline-light btn-lg btn-block rounded-pill" :href="stats.popular.post.url">View Post</a>
  47. </p>
  48. </div>
  49. </div>
  50. <div v-if="page == 6" class="text-center mw-500">
  51. <p class="display-4"><span class="font-weight-bold">{{stats.account.followers_this_year}}</span> New Followers</p>
  52. <p class="h3 font-weight-light mb-0">You followed <span class="font-weight-bold">{{stats.account.followed_this_year}}</span> accounts this year!</p>
  53. </div>
  54. <div v-if="page == 7" class="text-center mw-500">
  55. <div v-if="stats.account.hashtag">
  56. <p class="h1 text-break">Your favourite hashtag was <span class="font-weight-bold">#{{stats.account.hashtag.name}}</span>.</p>
  57. <p class="h3 font-weight-light mb-0">You used it <span class="font-weight-bold">{{stats.account.hashtag.count}}</span> times!</p>
  58. </div>
  59. <div v-else>
  60. <p class="h1 text-break">The most popular hashtag was <span class="font-weight-bold">#{{stats.popular.hashtag.name}}</span></p>
  61. <p class="h3 font-weight-light mb-0">It was used <span class="font-weight-bold">{{stats.popular.hashtag.count}}</span> times!</p>
  62. </div>
  63. </div>
  64. <div v-if="page == 8" class="text-center mw-500">
  65. <p class="display-4">You tagged <span class="font-weight-bold">{{stats.account.places_total}}</span> places.</p>
  66. <p v-if="stats.account.places_total" class="h3 font-weight-light mb-0">You tagged <span class="font-weight-bold">{{stats.account.places.name}}</span> a total of <span class="font-weight-bold">{{stats.account.places.count}}</span> times!</p>
  67. <p v-else class="h3 font-weight-light mb-0">The most tagged place was <span class="font-weight-bold">{{stats.popular.places.name}}</span> that was tagged a total of <span class="font-weight-bold">{{stats.popular.places.count}}</span> times!</p>
  68. </div>
  69. <div v-if="page == 9" class="text-center">
  70. <p class="display-4">Happy 2021!</p>
  71. <p class="h3 font-weight-light mb-0">We wish you the best in the new year.</p>
  72. </div>
  73. </div>
  74. <div v-if="loaded" class="fixed-top">
  75. <p class="text-center mt-3 d-flex justify-content-center align-items-center mb-0">
  76. <img src="/img/pixelfed-icon-grey.svg" width="60" height="60">
  77. <span class="text-light font-weight-bold ml-3" style="font-size: 22px;">#my2020</span>
  78. </p>
  79. </div>
  80. <div v-if="loaded" class="fixed-bottom">
  81. <p class="text-center">
  82. <a v-if="!notEnoughData" :class="prevClass()" href="#" @click.prevent="prevPage()" :disabled="page == 1"><i class="fas fa-chevron-left"></i> Back</a>
  83. <a class="btn btn-outline-light rounded-pill mx-3" href="/">Back to Pixelfed</a>
  84. <a v-if="!notEnoughData" :class="nextClass()" href="#" @click.prevent="nextPage()">Next <i class="fas fa-chevron-right"></i></a>
  85. </p>
  86. </div>
  87. </div>
  88. </template>
  89. <style type="text/css" scoped>
  90. .md-line-height {
  91. line-height: 1.65 !important;
  92. }
  93. .mw-500 {
  94. max-width: 500px;
  95. }
  96. </style>
  97. <script type="text/javascript">
  98. export default {
  99. data() {
  100. return {
  101. config: window.App.config,
  102. user: {},
  103. loggedIn: false,
  104. loaded: false,
  105. page: 1,
  106. stats: [],
  107. notEnoughData: false,
  108. reportedView: false
  109. }
  110. },
  111. mounted() {
  112. let u = new URLSearchParams(window.location.search);
  113. if( u.has('v') &&
  114. u.has('ned') &&
  115. u.has('sl') &&
  116. u.get('v') == 20 &&
  117. u.get('sl') >= 1 &&
  118. u.get('sl') <= 9
  119. ) {
  120. if(u.get('ned') == 0) {
  121. this.page = u.get('sl');
  122. } else {
  123. this.notEnoughData = true;
  124. }
  125. }
  126. axios.get('/api/pixelfed/v1/accounts/verify_credentials')
  127. .then(res => {
  128. this.user = res.data;
  129. window._sharedData.curUser = res.data;
  130. });
  131. this.fetchData();
  132. },
  133. updated() {
  134. },
  135. methods: {
  136. fetchData() {
  137. axios.get('/api/pixelfed/v2/seasonal/yir')
  138. .then(res => {
  139. this.stats = res.data;
  140. this.loaded = true;
  141. this.shortcuts();
  142. })
  143. },
  144. nextPage() {
  145. if(this.page == 9) {
  146. return;
  147. }
  148. if(this.page == 7 && this.stats.popular.places == null) {
  149. this.page = 9;
  150. window.history.pushState({}, {}, '/i/my2020?v=20&ned=0&sl=9');
  151. return;
  152. }
  153. if(this.page == 8) {
  154. axios.post('/api/pixelfed/v2/seasonal/yir', {
  155. 'profile_id' : this.user.profile_id
  156. })
  157. }
  158. ++this.page;
  159. window.history.pushState({}, {}, '/i/my2020?v=20&ned=0&sl=' + this.page);
  160. },
  161. prevPage() {
  162. if(this.page == 1) {
  163. return;
  164. }
  165. if(this.page == 9 && this.stats.popular.places == null) {
  166. this.page = 7;
  167. window.history.pushState({}, {}, '/i/my2020?v=20&ned=0&sl=7');
  168. return;
  169. }
  170. --this.page;
  171. if(this.page == 1) {
  172. window.history.pushState({}, {}, '/i/my2020');
  173. } else {
  174. window.history.pushState({}, {}, '/i/my2020?v=20&ned=0&sl=' + this.page);
  175. }
  176. },
  177. prevClass() {
  178. return this.page == 1
  179. ? 'btn btn-outline-muted rounded-pill'
  180. : 'btn btn-outline-light rounded-pill';
  181. },
  182. nextClass() {
  183. return this.page == 9
  184. ? 'btn btn-outline-muted rounded-pill'
  185. : 'btn btn-outline-light rounded-pill';
  186. },
  187. dateFormat(d) {
  188. },
  189. shortcuts() {
  190. let self = this;
  191. window.addEventListener("keydown", function(event) {
  192. if (event.defaultPrevented) {
  193. return;
  194. }
  195. switch(event.code) {
  196. case "KeyA":
  197. case "ArrowLeft":
  198. self.prevPage();
  199. break;
  200. case "KeyD":
  201. case "ArrowRight":
  202. self.nextPage();
  203. break;
  204. }
  205. event.preventDefault();
  206. }, true);
  207. }
  208. }
  209. }
  210. </script>