浏览代码

feat(Activities): added option to remove all activities for user

Signed-off-by: Jonathan <theflametrooper@gmail.com>
Jonathan 4 年之前
父节点
当前提交
bb1e2c8ae5

+ 59 - 1
backend/logic/actions/activities.js

@@ -9,6 +9,20 @@ const CacheModule = moduleManager.modules.cache;
 const IOModule = moduleManager.modules.io;
 const UtilsModule = moduleManager.modules.utils;
 
+CacheModule.runJob("SUB", {
+	channel: "activity.removeAllForUser",
+	cb: userId => {
+		IOModule.runJob("SOCKETS_FROM_USER", { userId }, this).then(res =>
+			res.sockets.forEach(socket => socket.emit("event:activity.removeAllForUser"))
+		);
+
+		IOModule.runJob("EMIT_TO_ROOM", {
+			room: `profile-${userId}-activities`,
+			args: ["event:activity.removeAllForUser"]
+		});
+	}
+});
+
 CacheModule.runJob("SUB", {
 	channel: "activity.hide",
 	cb: res => {
@@ -62,7 +76,7 @@ export default {
 						.find({ userId, hidden: false })
 						.skip(15 * (set - 1))
 						.limit(15)
-						.sort("createdAt")
+						.sort({ createdAt: -1 })
 						.exec(next);
 				}
 			],
@@ -115,5 +129,49 @@ export default {
 				return cb({ status: "success", message: "Successfully hid activity." });
 			}
 		);
+	}),
+
+	/**
+	 * Removes all activities logged for a logged-in user
+	 *
+	 * @param session
+	 * @param cb
+	 */
+	removeAllForUser: isLoginRequired(async function removeAllForUser(session, cb) {
+		const activityModel = await DBModule.runJob("GET_MODEL", { modelName: "activity" }, this);
+
+		async.waterfall(
+			[
+				next => {
+					activityModel.deleteMany({ userId: session.userId }, next);
+				}
+			],
+			async err => {
+				if (err) {
+					err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
+
+					this.log(
+						"ERROR",
+						"ACTIVITIES_REMOVE_ALL_FOR_USER",
+						`Failed to delete activities for user ${session.userId}. "${err}"`
+					);
+
+					return cb({ status: "failure", message: err });
+				}
+
+				CacheModule.runJob("PUB", {
+					channel: "activity.removeAllForUser",
+					value: session.userId
+				});
+
+				this.log(
+					"SUCCESS",
+					"ACTIVITIES_REMOVE_ALL_FOR_USER",
+					`Successfully removed activities for user ${session.userId}.`
+				);
+
+				return cb({ status: "success", message: "Successfully removed your activity logs." });
+			}
+		);
 	})
 };

+ 41 - 19
backend/logic/actions/stations.js

@@ -1460,15 +1460,26 @@ export default {
 					`Updated station "${stationId}" genres to "${newGenres}" successfully.`
 				);
 
-				ActivitiesModule.runJob("ADD_ACTIVITY", {
-					userId: session.userId,
-					type: "station__edit_genres",
-					payload: {
-						message: `Updated genres of station <stationId>${station.displayName}</stationId> to 
-						${newGenres.join(", ")}`,
-						stationId
-					}
-				});
+				if (newGenres.length > 0) {
+					ActivitiesModule.runJob("ADD_ACTIVITY", {
+						userId: session.userId,
+						type: "station__edit_genres",
+						payload: {
+							message: `Updated genres of station <stationId>${station.displayName}</stationId> to 
+							${newGenres.join(", ")}`,
+							stationId
+						}
+					});
+				} else {
+					ActivitiesModule.runJob("ADD_ACTIVITY", {
+						userId: session.userId,
+						type: "station__edit_genres",
+						payload: {
+							message: `Removed all genres of station <stationId>${station.displayName}</stationId>`,
+							stationId
+						}
+					});
+				}
 
 				return cb({
 					status: "success",
@@ -1532,16 +1543,27 @@ export default {
 					`Updated station "${stationId}" blacklisted genres to "${newBlacklistedGenres}" successfully.`
 				);
 
-				ActivitiesModule.runJob("ADD_ACTIVITY", {
-					userId: session.userId,
-					type: "station__edit_blacklisted_genres",
-					payload: {
-						message: `Updated blacklisted genres of station <stationId>${
-							station.displayName
-						}</stationId> to ${newBlacklistedGenres.join(", ")}`,
-						stationId
-					}
-				});
+				if (newBlacklistedGenres.length > 0) {
+					ActivitiesModule.runJob("ADD_ACTIVITY", {
+						userId: session.userId,
+						type: "station__edit_blacklisted_genres",
+						payload: {
+							message: `Updated blacklisted genres of station <stationId>${
+								station.displayName
+							}</stationId> to ${newBlacklistedGenres.join(", ")}`,
+							stationId
+						}
+					});
+				} else {
+					ActivitiesModule.runJob("ADD_ACTIVITY", {
+						userId: session.userId,
+						type: "station__edit_blacklisted_genres",
+						payload: {
+							message: `Removed all blacklisted genres of station <stationId>${station.displayName}</stationId>`,
+							stationId
+						}
+					});
+				}
 
 				return cb({
 					status: "success",

+ 6 - 1
frontend/src/pages/Profile/tabs/RecentActivity.vue

@@ -93,6 +93,10 @@ export default {
 			this.socket.on("event:activity.hide", activityId =>
 				this.removeActivity(activityId)
 			);
+
+			this.socket.on("event:activity.removeAllForUser", () =>
+				this.removeAllActivities()
+			);
 		});
 	},
 	methods: {
@@ -105,7 +109,8 @@ export default {
 		...mapActions("user/activities", [
 			"addSetOfActivities",
 			"addActivity",
-			"removeActivity"
+			"removeActivity",
+			"removeAllActivities"
 		])
 	}
 };

+ 24 - 0
frontend/src/pages/Settings/tabs/Security.vue

@@ -136,6 +136,25 @@
 				><i class="material-icons icon-with-button">exit_to_app</i>Log
 				out everywhere
 			</a>
+
+			<div class="section-margin-bottom" />
+		</div>
+
+		<div>
+			<h4 class="section-title">Clear my activities</h4>
+			<p class="section-description">
+				Permanently remove all my logged activity on Musare to date.
+			</p>
+
+			<hr class="section-horizontal-rule" />
+
+			<a
+				class="button is-warning"
+				href="#"
+				@click.prevent="deleteActivities()"
+				><i class="material-icons icon-with-button">delete</i>Clear my
+				activities
+			</a>
 		</div>
 	</div>
 </template>
@@ -250,6 +269,11 @@ export default {
 			this.socket.emit(`users.removeSessions`, this.userId, res => {
 				new Toast({ content: res.message, timeout: 4000 });
 			});
+		},
+		deleteActivities() {
+			this.socket.emit(`activities.removeAllForUser`, res => {
+				new Toast({ content: res.message, timeout: 4000 });
+			});
 		}
 	}
 };

+ 8 - 1
frontend/src/store/modules/user.js

@@ -213,7 +213,8 @@ const modules = {
 			addActivity: ({ commit }, activity) =>
 				commit("addActivity", activity),
 			removeActivity: ({ commit }, activityId) =>
-				commit("removeActivity", activityId)
+				commit("removeActivity", activityId),
+			removeAllActivities: ({ commit }) => commit("removeAllActivities")
 		},
 		mutations: {
 			addActivity(state, activity) {
@@ -232,6 +233,12 @@ const modules = {
 				state.activities = state.activities.filter(
 					activity => activity._id !== activityId
 				);
+			},
+			removeAllActivities(state) {
+				state.activities = [];
+				state.position = 0;
+				state.maxPosition = 1;
+				state.offsettedFromNextSet = 0;
 			}
 		}
 	},