WhatIsNew.vue 2.6 KB

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