WhatIsNew.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <template>
  2. <div v-if="news !== null">
  3. <modal title="News" class="what-is-news-modal">
  4. <div slot="body">
  5. <div
  6. class="section news-item"
  7. v-html="marked(news.markdown)"
  8. ></div>
  9. </div>
  10. <div slot="footer">
  11. <span v-if="news.createdBy">
  12. By
  13. <user-id-to-username
  14. :user-id="news.createdBy"
  15. :alt="news.createdBy"
  16. :link="true"/></span
  17. ><span :title="new Date(news.createdAt)">
  18. {{
  19. formatDistance(news.createdAt, new Date(), {
  20. addSuffix: true
  21. })
  22. }}
  23. </span>
  24. </div>
  25. </modal>
  26. </div>
  27. </template>
  28. <script>
  29. import { formatDistance } from "date-fns";
  30. import marked from "marked";
  31. import { mapGetters, mapActions } from "vuex";
  32. import UserIdToUsername from "@/components/UserIdToUsername.vue";
  33. import Modal from "../Modal.vue";
  34. export default {
  35. components: { Modal, UserIdToUsername },
  36. data() {
  37. return {
  38. isModalActive: false,
  39. news: null
  40. };
  41. },
  42. computed: {
  43. ...mapGetters({
  44. socket: "websockets/getSocket"
  45. })
  46. },
  47. mounted() {
  48. marked.use({
  49. renderer: {
  50. table(header, body) {
  51. return `<table class="table is-striped">
  52. <thead>${header}</thead>
  53. <tbody>${body}</tbody>
  54. </table>`;
  55. }
  56. }
  57. });
  58. this.socket.dispatch("news.newest", res => {
  59. if (res.status !== "success") return;
  60. const { news } = res.data;
  61. this.news = news;
  62. if (this.news && localStorage.getItem("firstVisited")) {
  63. if (localStorage.getItem("whatIsNew")) {
  64. if (
  65. parseInt(localStorage.getItem("whatIsNew")) <
  66. news.createdAt
  67. ) {
  68. this.openModal("whatIsNew");
  69. localStorage.setItem("whatIsNew", news.createdAt);
  70. }
  71. } else {
  72. if (
  73. parseInt(localStorage.getItem("firstVisited")) <
  74. news.createdAt
  75. )
  76. this.openModal("whatIsNew");
  77. localStorage.setItem("whatIsNew", news.createdAt);
  78. }
  79. } else if (!localStorage.getItem("firstVisited"))
  80. localStorage.setItem("firstVisited", Date.now());
  81. });
  82. },
  83. methods: {
  84. marked,
  85. formatDistance,
  86. ...mapActions("modalVisibility", ["openModal"])
  87. }
  88. };
  89. </script>
  90. <style lang="scss">
  91. .what-is-news-modal {
  92. .modal-card {
  93. .modal-card-foot {
  94. span:not(:last-child) {
  95. margin-right: 5px !important;
  96. }
  97. }
  98. }
  99. }
  100. </style>
  101. <style lang="scss" scoped>
  102. .night-mode {
  103. .modal-card,
  104. .modal-card-head,
  105. .modal-card-body {
  106. background-color: var(--dark-grey-3);
  107. }
  108. strong,
  109. p {
  110. color: var(--light-grey-2);
  111. }
  112. }
  113. .modal-card-head {
  114. border-bottom: none;
  115. background-color: ghostwhite;
  116. padding: 15px;
  117. }
  118. .modal-card-title {
  119. font-size: 14px;
  120. }
  121. .news-item {
  122. box-shadow: unset !important;
  123. }
  124. .delete {
  125. background: transparent;
  126. &:hover {
  127. background: transparent;
  128. }
  129. &:before,
  130. &:after {
  131. background-color: var(--light-grey-3);
  132. }
  133. }
  134. .sect {
  135. div[class^="sect-head"],
  136. div[class*=" sect-head"] {
  137. padding: 12px;
  138. text-transform: uppercase;
  139. font-weight: bold;
  140. color: var(--white);
  141. }
  142. .sect-head-features {
  143. background-color: dodgerblue;
  144. }
  145. .sect-head-improvements {
  146. background-color: seagreen;
  147. }
  148. .sect-head-bugs {
  149. background-color: brown;
  150. }
  151. .sect-head-upcoming {
  152. background-color: mediumpurple;
  153. }
  154. .sect-body {
  155. padding: 15px 25px;
  156. li {
  157. list-style-type: disc;
  158. }
  159. }
  160. }
  161. </style>