Browse Source

feat(Activities): report items can be referenced/opened from an Activity Item

Signed-off-by: Jonathan <theflametrooper@gmail.com>
Jonathan 3 years ago
parent
commit
3824206a5a

+ 2 - 1
backend/logic/actions/reports.js

@@ -481,8 +481,9 @@ export default {
 					userId: session.userId,
 					type: "song__report",
 					payload: {
-						message: `Reported song <youtubeId>${song.title} by ${song.artists.join(", ")}</youtubeId>`,
+						message: `Created a <reportId>${report._id}</reportId> for song <youtubeId>${song.title}</youtubeId>`,
 						youtubeId: report.song.youtubeId,
+						reportId: report._id,
 						thumbnail: song.thumbnail
 					}
 				});

+ 11 - 1
backend/logic/activities.js

@@ -44,6 +44,7 @@ class _ActivitiesModule extends CoreClass {
 	 * @param {string} payload.payload.message - the main message describing the activity e.g. 50 songs added to playlist 'playlist name'
 	 * @param {string} payload.payload.thumbnail - url to a thumbnail e.g. song album art to be used when display an activity
 	 * @param {string} payload.payload.youtubeId - (optional) if relevant, the youtube id of the song related to the activity
+	 * @param {string} payload.payload.reportId - (optional) if relevant, the id of the report related to the activity
 	 * @param {string} payload.payload.playlistId - (optional) if relevant, the id of the playlist related to the activity
 	 * @param {string} payload.payload.stationId - (optional) if relevant, the id of the station related to the activity
 	 * @returns {Promise} - returns promise (reject, resolve)
@@ -300,8 +301,9 @@ class _ActivitiesModule extends CoreClass {
 	 * Removes any references to a station, playlist or song in activities
 	 *
 	 * @param {object} payload - object that contains the payload
-	 * @param {string} payload.type - type of reference. enum: ["youtubeId", "stationId", "playlistId"]
+	 * @param {string} payload.type - type of reference. enum: ["youtubeId", "stationId", "playlistId", "playlistId"]
 	 * @param {string} payload.stationId - (optional) the id of a station
+	 * @param {string} payload.reportId - (optional) the id of a report
 	 * @param {string} payload.playlistId - (optional) the id of a playlist
 	 * @param {string} payload.youtubeId - (optional) the id of a song
 	 * @returns {Promise} - returns promise (reject, resolve)
@@ -316,6 +318,7 @@ class _ActivitiesModule extends CoreClass {
 						if (
 							(payload.type !== "youtubeId" &&
 								payload.type !== "stationId" &&
+								payload.type !== "reportId" &&
 								payload.type !== "playlistId") ||
 							!payload.type
 						)
@@ -351,6 +354,13 @@ class _ActivitiesModule extends CoreClass {
 									);
 								}
 
+								if (payload.reportId) {
+									activity.payload.message = activity.payload.message.replace(
+										/<reportId>(.*)<\/reportId>/g,
+										"$1"
+									);
+								}
+
 								if (payload.playlistId) {
 									activity.payload.message = activity.payload.message.replace(
 										/<playlistId>(.*)<\/playlistId>/g,

+ 2 - 1
backend/logic/db/schemas/activity.js

@@ -50,7 +50,8 @@ export default {
 		thumbnail: { type: String, required: false },
 		youtubeId: { type: String, required: false },
 		stationId: { type: String, required: false },
-		playlistId: { type: String, required: false }
+		playlistId: { type: String, required: false },
+		reportId: { type: String, required: false }
 	},
 	documentVersion: { type: Number, default: 2, required: true }
 };

+ 36 - 4
frontend/src/components/ActivityItem.vue

@@ -46,7 +46,12 @@ export default {
 	},
 	computed: {
 		formattedMessage() {
-			const { youtubeId, playlistId, stationId } = this.activity.payload;
+			const {
+				youtubeId,
+				playlistId,
+				stationId,
+				reportId
+			} = this.activity.payload;
 			let { message } = this.activity.payload;
 
 			if (youtubeId) {
@@ -56,6 +61,13 @@ export default {
 				);
 			}
 
+			if (reportId) {
+				message = message.replace(
+					/<reportId>(.*)<\/reportId>/g,
+					`<a href='#' class='activity-item-link' @click='showReport("${reportId}")'>report</a>`
+				);
+			}
+
 			if (playlistId) {
 				message = message.replace(
 					/<playlistId>(.*)<\/playlistId>/g,
@@ -72,13 +84,28 @@ export default {
 
 			return {
 				template: `<p>${message}</p>`,
-				methods: { showPlaylist: this.showPlaylist }
+				methods: {
+					showPlaylist: this.showPlaylist,
+					showReport: this.showReport
+				}
 			};
 		},
 		textOnlyMessage() {
-			const { youtubeId, playlistId, stationId } = this.activity.payload;
+			const {
+				youtubeId,
+				playlistId,
+				stationId,
+				reportId
+			} = this.activity.payload;
 			let { message } = this.activity.payload;
 
+			if (reportId) {
+				message = message.replace(
+					/<reportId>(.*)<\/reportId>/g,
+					"report"
+				);
+			}
+
 			if (youtubeId) {
 				message = message.replace(
 					/<youtubeId>(.*)<\/youtubeId>/g,
@@ -154,6 +181,10 @@ export default {
 
 			return icons[this.activity.type];
 		},
+		showReport(reportId) {
+			this.viewReport(reportId);
+			this.openModal("viewReport");
+		},
 		showPlaylist(playlistId) {
 			this.editPlaylist(playlistId);
 			this.openModal("editPlaylist");
@@ -161,7 +192,8 @@ export default {
 		...mapActions("user/playlists", ["editPlaylist"]),
 		formatDistance,
 		parseISO,
-		...mapActions("modalVisibility", ["openModal"])
+		...mapActions("modalVisibility", ["openModal"]),
+		...mapActions("modals/viewReport", ["viewReport"])
 	}
 };
 </script>

+ 5 - 1
frontend/src/components/ReportInfoItem.vue

@@ -18,6 +18,7 @@
 						path: `/u/${createdBy.username}`
 					}"
 					:title="createdBy._id"
+					@click="closeModal('viewReport')"
 				>
 					{{ createdBy.username }}
 				</router-link>
@@ -39,7 +40,9 @@
 </template>
 
 <script>
+import { mapActions } from "vuex";
 import { formatDistance } from "date-fns";
+
 import ProfilePicture from "@/components/ProfilePicture.vue";
 
 export default {
@@ -49,7 +52,8 @@ export default {
 		createdAt: { type: String, default: "" }
 	},
 	methods: {
-		formatDistance
+		formatDistance,
+		...mapActions("modalVisibility", ["closeModal"])
 	}
 };
 </script>

+ 4 - 5
frontend/src/components/modals/Report.vue

@@ -193,7 +193,7 @@
 				</a>
 			</template>
 		</modal>
-		<view-report v-if="modals.viewReport" :report-id="viewingReportId" />
+		<view-report v-if="modals.viewReport" />
 	</div>
 </template>
 
@@ -210,7 +210,6 @@ export default {
 	components: { Modal, ViewReport, SongItem, ReportInfoItem },
 	data() {
 		return {
-			viewingReportId: "",
 			icons: {
 				duration: "timer",
 				video: "tv",
@@ -376,7 +375,7 @@ export default {
 	},
 	methods: {
 		view(reportId) {
-			this.viewingReportId = reportId;
+			this.viewReport(reportId);
 			this.openModal("viewReport");
 		},
 		create() {
@@ -414,8 +413,8 @@ export default {
 				}
 			);
 		},
-		...mapActions("modals/report", ["reportSong"]),
-		...mapActions("modalVisibility", ["openModal", "closeModal"])
+		...mapActions("modalVisibility", ["openModal", "closeModal"]),
+		...mapActions("modals/viewReport", ["viewReport"])
 	}
 };
 </script>

+ 11 - 9
frontend/src/components/modals/ViewReport.vue

@@ -54,7 +54,7 @@
 								content="Resolve"
 								v-tippy
 								v-if="!issue.resolved"
-								@click="toggleIssue(report._id, issue._id)"
+								@click="toggleIssue(issue._id)"
 							>
 								done
 							</i>
@@ -63,7 +63,7 @@
 								content="Unresolve"
 								v-tippy
 								v-else
-								@click="toggleIssue(report._id, issue._id)"
+								@click="toggleIssue(issue._id)"
 							>
 								remove
 							</i>
@@ -83,7 +83,7 @@
 				</i>
 				Edit Song
 			</a>
-			<a class="button is-success" href="#" @click="resolve(report._id)">
+			<a class="button is-success" href="#" @click="resolve()">
 				<i
 					class="material-icons icon-with-button"
 					content="Resolve"
@@ -98,7 +98,7 @@
 </template>
 
 <script>
-import { mapActions, mapGetters } from "vuex";
+import { mapActions, mapGetters, mapState } from "vuex";
 import Toast from "toasters";
 
 import Modal from "@/components/Modal.vue";
@@ -108,7 +108,6 @@ import ReportInfoItem from "@/components/ReportInfoItem.vue";
 export default {
 	components: { Modal, SongItem, ReportInfoItem },
 	props: {
-		reportId: { type: String, default: "" },
 		sector: { type: String, default: "admin" }
 	},
 	data() {
@@ -126,6 +125,9 @@ export default {
 		};
 	},
 	computed: {
+		...mapState("modals/viewReport", {
+			reportId: state => state.viewingReportId
+		}),
 		...mapGetters({
 			socket: "websockets/getSocket"
 		})
@@ -185,17 +187,17 @@ export default {
 		this.socket.dispatch("apis.leaveRoom", `view-report.${this.reportId}`);
 	},
 	methods: {
-		resolve(reportId) {
-			return this.resolveReport(reportId)
+		resolve() {
+			return this.resolveReport(this.reportId)
 				.then(res => {
 					if (res.status === "success") this.closeModal("viewReport");
 				})
 				.catch(err => new Toast(err.message));
 		},
-		toggleIssue(reportId, issueId) {
+		toggleIssue(issueId) {
 			this.socket.dispatch(
 				"reports.toggleIssue",
-				reportId,
+				this.reportId,
 				issueId,
 				res => {
 					if (res.status !== "success") new Toast(res.message);

+ 4 - 8
frontend/src/pages/Admin/tabs/Reports.vue

@@ -78,11 +78,7 @@
 			</table>
 		</div>
 
-		<view-report
-			v-if="modals.viewReport"
-			:report-id="viewingReportId"
-			sector="admin"
-		/>
+		<view-report v-if="modals.viewReport" sector="admin" />
 
 		<edit-song v-if="modals.editSong" song-type="songs" />
 	</div>
@@ -108,7 +104,6 @@ export default {
 	},
 	data() {
 		return {
-			viewingReportId: "",
 			reports: []
 		};
 	},
@@ -164,7 +159,7 @@ export default {
 			return categories;
 		},
 		view(reportId) {
-			this.viewingReportId = reportId;
+			this.viewReport(reportId);
 			this.openModal("viewReport");
 		},
 		resolve(reportId) {
@@ -176,7 +171,8 @@ export default {
 				.catch(err => new Toast(err.message));
 		},
 		...mapActions("modalVisibility", ["openModal", "closeModal"]),
-		...mapActions("admin/reports", ["resolveReport"])
+		...mapActions("admin/reports", ["resolveReport"]),
+		...mapActions("modals/viewReport", ["viewReport"])
 	}
 };
 </script>

+ 4 - 0
frontend/src/pages/Profile/index.vue

@@ -2,6 +2,7 @@
 	<div v-if="isUser">
 		<edit-playlist v-if="modals.editPlaylist" />
 		<report v-if="modals.report" />
+		<view-report v-if="modals.viewReport" />
 		<edit-song v-if="modals.editSong" song-type="songs" />
 
 		<metadata :title="`Profile | ${user.username}`" />
@@ -131,6 +132,9 @@ export default {
 		Report: defineAsyncComponent(() =>
 			import("@/components/modals/Report.vue")
 		),
+		ViewReport: defineAsyncComponent(() =>
+			import("@/components/modals/ViewReport.vue")
+		),
 		EditSong: defineAsyncComponent(() =>
 			import("@/components/modals/EditSong")
 		)

+ 3 - 1
frontend/src/store/index.js

@@ -15,6 +15,7 @@ import editPlaylistModal from "./modules/modals/editPlaylist";
 import manageStationModal from "./modules/modals/manageStation";
 import editUserModal from "./modules/modals/editUser";
 import viewPunishmentModal from "./modules/modals/viewPunishment";
+import viewReportModal from "./modules/modals/viewReport";
 import reportModal from "./modules/modals/report";
 
 export default createStore({
@@ -34,7 +35,8 @@ export default createStore({
 				manageStation: manageStationModal,
 				editUser: editUserModal,
 				viewPunishment: viewPunishmentModal,
-				report: reportModal
+				report: reportModal,
+				viewReport: viewReportModal
 			}
 		}
 	},

+ 16 - 0
frontend/src/store/modules/modals/viewReport.js

@@ -0,0 +1,16 @@
+/* eslint no-param-reassign: 0 */
+
+export default {
+	namespaced: true,
+	state: {
+		viewingReportId: ""
+	},
+	actions: {
+		viewReport: ({ commit }, reportId) => commit("viewReport", reportId)
+	},
+	mutations: {
+		viewReport(state, reportId) {
+			state.viewingReportId = reportId;
+		}
+	}
+};