RecentActivity.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <template>
  2. <div class="content recent-activity-tab">
  3. <div v-if="activities.length > 0">
  4. <h4 class="section-title">Recent activity</h4>
  5. <p class="section-description">
  6. This is a log of all actions
  7. {{ userId === myUserId ? "you have" : `${username} has` }}
  8. taken recently
  9. </p>
  10. <hr class="section-horizontal-rule" />
  11. <div id="activity-items">
  12. <activity-item
  13. class="item activity-item universal-item"
  14. v-for="activity in activities"
  15. :key="activity._id"
  16. :activity="activity"
  17. >
  18. <template #actions>
  19. <quick-confirm
  20. v-if="userId === myUserId"
  21. @confirm="hideActivity(activity._id)"
  22. >
  23. <a content="Hide Activity" v-tippy>
  24. <i class="material-icons hide-icon"
  25. >visibility_off</i
  26. >
  27. </a>
  28. </quick-confirm>
  29. </template>
  30. </activity-item>
  31. </div>
  32. </div>
  33. <div v-else>
  34. <h5>No recent activity.</h5>
  35. </div>
  36. </div>
  37. </template>
  38. <script>
  39. import { mapState, mapGetters, mapActions } from "vuex";
  40. import Toast from "toasters";
  41. import ActivityItem from "@/components/ActivityItem.vue";
  42. import ws from "@/ws";
  43. export default {
  44. components: { ActivityItem },
  45. props: {
  46. userId: {
  47. type: String,
  48. default: ""
  49. }
  50. },
  51. data() {
  52. return {
  53. username: "",
  54. activities: [],
  55. position: 1,
  56. maxPosition: 1,
  57. offsettedFromNextSet: 0,
  58. isGettingSet: false
  59. };
  60. },
  61. computed: {
  62. ...mapState({
  63. myUserId: state => state.user.auth.userId
  64. }),
  65. ...mapGetters({
  66. socket: "websockets/getSocket"
  67. })
  68. },
  69. mounted() {
  70. window.addEventListener("scroll", this.handleScroll);
  71. ws.onConnect(this.init);
  72. this.socket.on("event:activity.updated", res => {
  73. this.activities.find(
  74. activity => activity._id === res.data.activityId
  75. ).payload.message = res.data.message;
  76. });
  77. this.socket.on("event:activity.created", res => {
  78. this.activities.unshift(res.data.activity);
  79. this.offsettedFromNextSet += 1;
  80. });
  81. this.socket.on("event:activity.hidden", res => {
  82. this.activities = this.activities.filter(
  83. activity => activity._id !== res.data.activityId
  84. );
  85. this.offsettedFromNextSet -= 1;
  86. });
  87. this.socket.on("event:activity.removeAllForUser", () => {
  88. this.activities = [];
  89. this.position = 1;
  90. this.maxPosition = 1;
  91. this.offsettedFromNextSet = 0;
  92. });
  93. },
  94. unmounted() {
  95. window.removeEventListener("scroll", this.handleScroll);
  96. },
  97. methods: {
  98. init() {
  99. if (this.myUserId !== this.userId)
  100. this.getUsernameFromId(this.userId).then(username => {
  101. if (username) this.username = username;
  102. });
  103. this.socket.dispatch("activities.length", this.userId, res => {
  104. if (res.status === "success") {
  105. this.maxPosition = Math.ceil(res.data.length / 15) + 1;
  106. this.getSet();
  107. }
  108. });
  109. },
  110. hideActivity(activityId) {
  111. this.socket.dispatch("activities.hideActivity", activityId, res => {
  112. if (res.status !== "success") new Toast(res.message);
  113. });
  114. },
  115. getSet() {
  116. if (this.isGettingSet) return;
  117. if (this.position >= this.maxPosition) return;
  118. this.isGettingSet = true;
  119. this.socket.dispatch(
  120. "activities.getSet",
  121. this.userId,
  122. this.position,
  123. this.offsettedFromNextSet,
  124. res => {
  125. if (res.status === "success") {
  126. this.activities.push(...res.data.activities);
  127. this.position += 1;
  128. }
  129. this.isGettingSet = false;
  130. }
  131. );
  132. },
  133. handleScroll() {
  134. const scrollPosition = document.body.clientHeight + window.scrollY;
  135. const bottomPosition = document.body.scrollHeight;
  136. if (scrollPosition + 400 >= bottomPosition) this.getSet();
  137. return this.maxPosition === this.position;
  138. },
  139. ...mapActions("user/auth", ["getUsernameFromId"])
  140. }
  141. };
  142. </script>
  143. <style lang="less" scoped>
  144. .night-mode #activity-items .activity-item {
  145. background-color: var(--dark-grey-2) !important;
  146. border: 0 !important;
  147. }
  148. .content a {
  149. border-bottom: 0;
  150. }
  151. </style>