RecentActivity.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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. <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. </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. import Confirm from "@/components/Confirm.vue";
  44. export default {
  45. components: { ActivityItem, Confirm },
  46. props: {
  47. userId: {
  48. type: String,
  49. default: ""
  50. }
  51. },
  52. data() {
  53. return {
  54. username: "",
  55. activities: [],
  56. position: 1,
  57. maxPosition: 1,
  58. offsettedFromNextSet: 0,
  59. isGettingSet: false
  60. };
  61. },
  62. computed: {
  63. ...mapState({
  64. ...mapState("modalVisibility", {
  65. modals: state => state.modals
  66. }),
  67. myUserId: state => state.user.auth.userId
  68. }),
  69. ...mapGetters({
  70. socket: "websockets/getSocket"
  71. })
  72. },
  73. mounted() {
  74. window.addEventListener("scroll", this.handleScroll);
  75. ws.onConnect(this.init);
  76. this.socket.on("event:activity.updated", res => {
  77. this.activities.find(
  78. activity => activity._id === res.data.activityId
  79. ).payload.message = res.data.message;
  80. });
  81. this.socket.on("event:activity.created", res => {
  82. this.activities.unshift(res.data.activity);
  83. this.offsettedFromNextSet += 1;
  84. });
  85. this.socket.on("event:activity.hidden", res => {
  86. this.activities = this.activities.filter(
  87. activity => activity._id !== res.data.activityId
  88. );
  89. this.offsettedFromNextSet -= 1;
  90. });
  91. this.socket.on("event:activity.removeAllForUser", () => {
  92. this.activities = [];
  93. this.position = 1;
  94. this.maxPosition = 1;
  95. this.offsettedFromNextSet = 0;
  96. });
  97. },
  98. unmounted() {
  99. window.removeEventListener("scroll", this.handleScroll);
  100. },
  101. methods: {
  102. init() {
  103. if (this.myUserId !== this.userId)
  104. this.getUsernameFromId(this.userId).then(username => {
  105. if (username) this.username = username;
  106. });
  107. this.socket.dispatch("activities.length", this.userId, res => {
  108. if (res.status === "success") {
  109. this.maxPosition = Math.ceil(res.data.length / 15) + 1;
  110. this.getSet();
  111. }
  112. });
  113. },
  114. hideActivity(activityId) {
  115. this.socket.dispatch("activities.hideActivity", activityId, res => {
  116. if (res.status !== "success") new Toast(res.message);
  117. });
  118. },
  119. getSet() {
  120. if (this.isGettingSet) return;
  121. if (this.position >= this.maxPosition) return;
  122. this.isGettingSet = true;
  123. this.socket.dispatch(
  124. "activities.getSet",
  125. this.userId,
  126. this.position,
  127. this.offsettedFromNextSet,
  128. res => {
  129. if (res.status === "success") {
  130. this.activities.push(...res.data.activities);
  131. this.position += 1;
  132. }
  133. this.isGettingSet = false;
  134. }
  135. );
  136. },
  137. handleScroll() {
  138. const scrollPosition = document.body.clientHeight + window.scrollY;
  139. const bottomPosition = document.body.scrollHeight;
  140. if (this.loadAllSongs) return false;
  141. if (scrollPosition + 400 >= bottomPosition) this.getSet();
  142. return this.maxPosition === this.position;
  143. },
  144. ...mapActions("user/auth", ["getUsernameFromId"])
  145. }
  146. };
  147. </script>
  148. <style lang="scss" scoped>
  149. .night-mode #activity-items .activity-item {
  150. background-color: var(--dark-grey-2) !important;
  151. border: 0 !important;
  152. }
  153. .content a {
  154. border-bottom: 0;
  155. }
  156. </style>