Browse Source

feat: made ActivityWatch integration compatible with SoundCloud

Kristian Vos 1 year ago
parent
commit
b329bc25e1

+ 10 - 10
frontend/src/aw.ts

@@ -6,7 +6,7 @@ let pingTries = 0;
 let uuid = null;
 let enabled = false;
 
-let lastTimeSentVideoDate = 0;
+let lastTimeSentMediaDate = 0;
 let lastTimeDenied = 0;
 let lastTimeCompetitor = 0;
 
@@ -18,13 +18,13 @@ const notConnectedToast = new Toast({
 
 notConnectedToast.hide();
 
-const sendingVideoDataToast = new Toast({
-	content: "Sending video data to ActivityWatch.",
+const sendingMediaDataToast = new Toast({
+	content: "Sending media data to ActivityWatch.",
 	persistent: true,
 	interactable: false
 });
 
-sendingVideoDataToast.hide();
+sendingMediaDataToast.hide();
 
 const deniedToast = new Toast({
 	content:
@@ -45,10 +45,10 @@ const competitorToast = new Toast({
 competitorToast.hide();
 
 export default {
-	sendVideoData(videoData) {
+	sendMediaData(mediaData) {
 		if (enabled) {
-			lastTimeSentVideoDate = Date.now();
-			this.sendEvent("videoData", videoData);
+			lastTimeSentMediaDate = Date.now();
+			this.sendEvent("videoData", mediaData);
 		}
 	},
 
@@ -97,11 +97,11 @@ export default {
 				if (
 					!(lastTimeDenied + 1000 > Date.now()) &&
 					!(lastTimeCompetitor + 1000 > Date.now()) &&
-					lastTimeSentVideoDate + 1000 > Date.now()
+					lastTimeSentMediaDate + 1000 > Date.now()
 				) {
-					sendingVideoDataToast.show();
+					sendingMediaDataToast.show();
 				} else {
-					sendingVideoDataToast.hide();
+					sendingMediaDataToast.hide();
 				}
 			}, 1000);
 		}

+ 18 - 17
frontend/src/components/modals/EditSong/index.vue

@@ -106,9 +106,9 @@ const youtubeVideoNote = ref("");
 const useHTTPS = ref(false);
 const muted = ref(false);
 const volumeSliderValue = ref(0);
-const activityWatchVideoDataInterval = ref(null);
-const activityWatchVideoLastStatus = ref("");
-const activityWatchVideoLastStartDuration = ref(0);
+const activityWatchMediaDataInterval = ref(null);
+const activityWatchMediaLastStatus = ref("");
+const activityWatchMediaLastStartDuration = ref(0);
 const recommendedGenres = ref([
 	"Blues",
 	"Country",
@@ -1099,25 +1099,26 @@ const resetGenreHelper = () => {
 	genreHelper.value.resetBox();
 };
 
-const sendActivityWatchVideoData = () => {
+const sendActivityWatchMediaData = () => {
 	// TODO have this support soundcloud
 	if (
-		currentSongMediaType.value === "youtube" &&
 		!video.value.paused &&
-		video.value.player.getPlayerState() === window.YT.PlayerState.PLAYING
+		(currentSongMediaType.value !== "youtube" ||
+			video.value.player.getPlayerState() ===
+				window.YT.PlayerState.PLAYING)
 	) {
-		if (activityWatchVideoLastStatus.value !== "playing") {
-			activityWatchVideoLastStatus.value = "playing";
+		if (activityWatchMediaLastStatus.value !== "playing") {
+			activityWatchMediaLastStatus.value = "playing";
 			if (
 				inputs.value.skipDuration.value > 0 &&
 				Number(youtubeVideoCurrentTime.value) === 0
 			) {
-				activityWatchVideoLastStartDuration.value = Math.floor(
+				activityWatchMediaLastStartDuration.value = Math.floor(
 					inputs.value.skipDuration.value +
 						Number(youtubeVideoCurrentTime.value)
 				);
 			} else {
-				activityWatchVideoLastStartDuration.value = Math.floor(
+				activityWatchMediaLastStartDuration.value = Math.floor(
 					Number(youtubeVideoCurrentTime.value)
 				);
 			}
@@ -1132,9 +1133,9 @@ const sendActivityWatchVideoData = () => {
 			muted: muted.value,
 			volume: volumeSliderValue.value,
 			startedDuration:
-				activityWatchVideoLastStartDuration.value <= 0
+				activityWatchMediaLastStartDuration.value <= 0
 					? 0
-					: activityWatchVideoLastStartDuration.value,
+					: activityWatchMediaLastStartDuration.value,
 			source: `editSong#${inputs.value.mediaSource.value}`,
 			hostname: window.location.hostname,
 			playerState: Object.keys(window.YT.PlayerState).find(
@@ -1145,9 +1146,9 @@ const sendActivityWatchVideoData = () => {
 			playbackRate: video.value.playbackRate
 		};
 
-		aw.sendVideoData(videoData);
+		aw.sendMediaData(videoData);
 	} else {
-		activityWatchVideoLastStatus.value = "not_playing";
+		activityWatchMediaLastStatus.value = "not_playing";
 	}
 };
 
@@ -1215,8 +1216,8 @@ onMounted(async () => {
 	};
 	preventCloseCbs[props.modalUuid] = onCloseOrNext;
 
-	activityWatchVideoDataInterval.value = setInterval(() => {
-		sendActivityWatchVideoData();
+	activityWatchMediaDataInterval.value = setInterval(() => {
+		sendActivityWatchMediaData();
 	}, 1000);
 
 	useHTTPS.value = await lofig.get("cookie.secure");
@@ -1835,7 +1836,7 @@ onBeforeUnmount(() => {
 
 	youtubePlayerReady.value = false;
 	clearInterval(interval.value);
-	clearInterval(activityWatchVideoDataInterval.value);
+	clearInterval(activityWatchMediaDataInterval.value);
 
 	const shortcutNames = [
 		"editSong.pauseResume",

+ 15 - 15
frontend/src/components/modals/ViewYoutubeVideo.vue

@@ -33,9 +33,9 @@ const loaded = ref(false);
 const canvasWidth = ref(760);
 const volumeSliderValue = ref(20);
 const durationCanvas = ref(null);
-const activityWatchVideoDataInterval = ref(null);
-const activityWatchVideoLastStatus = ref("");
-const activityWatchVideoLastStartDuration = ref(0);
+const activityWatchMediaDataInterval = ref(null);
+const activityWatchMediaLastStatus = ref("");
+const activityWatchMediaLastStartDuration = ref(0);
 
 const viewYoutubeVideoStore = useViewYoutubeVideoStore({
 	modalUuid: props.modalUuid
@@ -186,14 +186,14 @@ const setTrackPosition = event => {
 		)
 	);
 };
-const sendActivityWatchVideoData = () => {
+const sendActivityWatchMediaData = () => {
 	if (
 		!player.value.paused &&
 		player.value.player.getPlayerState() === window.YT.PlayerState.PLAYING
 	) {
-		if (activityWatchVideoLastStatus.value !== "playing") {
-			activityWatchVideoLastStatus.value = "playing";
-			activityWatchVideoLastStartDuration.value = Math.floor(
+		if (activityWatchMediaLastStatus.value !== "playing") {
+			activityWatchMediaLastStatus.value = "playing";
+			activityWatchMediaLastStartDuration.value = Math.floor(
 				Number(player.value.currentTime)
 			);
 		}
@@ -201,13 +201,13 @@ const sendActivityWatchVideoData = () => {
 		const videoData = {
 			title: video.value.title,
 			artists: video.value.author,
-			youtubeId: video.value.youtubeId,
+			mediaSource: `youtube:${video.value.youtubeId}`,
 			muted: player.value.muted,
 			volume: player.value.volume,
 			startedDuration:
-				activityWatchVideoLastStartDuration.value <= 0
+				activityWatchMediaLastStartDuration.value <= 0
 					? 0
-					: activityWatchVideoLastStartDuration.value,
+					: activityWatchMediaLastStartDuration.value,
 			source: `viewYoutubeVideo#${video.value.youtubeId}`,
 			hostname: window.location.hostname,
 			playerState: Object.keys(window.YT.PlayerState).find(
@@ -218,9 +218,9 @@ const sendActivityWatchVideoData = () => {
 			playbackRate: player.value.playbackRate
 		};
 
-		aw.sendVideoData(videoData);
+		aw.sendMediaData(videoData);
 	} else {
-		activityWatchVideoLastStatus.value = "not_playing";
+		activityWatchMediaLastStatus.value = "not_playing";
 	}
 };
 
@@ -286,8 +286,8 @@ onMounted(() => {
 					if (player.value.paused === false) drawCanvas();
 				}, 200);
 
-				activityWatchVideoDataInterval.value = setInterval(() => {
-					sendActivityWatchVideoData();
+				activityWatchMediaDataInterval.value = setInterval(() => {
+					sendActivityWatchMediaData();
 				}, 1000);
 
 				if (window.YT && window.YT.Player) {
@@ -468,7 +468,7 @@ onBeforeUnmount(() => {
 	player.value.playerReady = false;
 	player.value.videoNote = "";
 	clearInterval(interval.value);
-	clearInterval(activityWatchVideoDataInterval.value);
+	clearInterval(activityWatchMediaDataInterval.value);
 	loaded.value = false;
 
 	socket.dispatch(

+ 34 - 25
frontend/src/pages/Station/index.vue

@@ -93,10 +93,10 @@ const volumeSliderValue = ref(0);
 const showPlaylistDropdown = ref(false);
 const seekerbarPercentage = ref(0);
 const frontendDevMode = ref("production");
-const activityWatchVideoDataInterval = ref(null);
-const activityWatchVideoLastStatus = ref("");
-const activityWatchVideoLastYouTubeId = ref("");
-const activityWatchVideoLastStartDuration = ref(0);
+const activityWatchMediaDataInterval = ref(null);
+const activityWatchMediaLastStatus = ref("");
+const activityWatchMediaLastMediaSource = ref("");
+const activityWatchMediaLastStartDuration = ref(0);
 const reportStationStateInterval = ref(null);
 const nextCurrentSong = ref(null);
 const mediaModalWatcher = ref(null);
@@ -1044,31 +1044,31 @@ const toggleKeyboardShortcutsHelper = () => {
 const resetKeyboardShortcutsHelper = () => {
 	keyboardShortcutsHelper.value.resetBox();
 };
-const sendActivityWatchVideoData = () => {
+const sendActivityWatchMediaData = () => {
 	// TODO have this support soundcloud
 	if (
-		currentSongMediaType.value === "youtube" &&
 		!stationPaused.value &&
 		(!localPaused.value ||
 			experimentalChangableListenMode.value === "participate") &&
 		!noSong.value &&
 		(experimentalChangableListenMode.value === "participate" ||
+			currentSongMediaType.value !== "youtube" ||
 			youtubePlayer.value.getPlayerState() ===
 				window.YT.PlayerState.PLAYING)
 	) {
-		if (activityWatchVideoLastStatus.value !== "playing") {
-			activityWatchVideoLastStatus.value = "playing";
-			activityWatchVideoLastStartDuration.value =
+		if (activityWatchMediaLastStatus.value !== "playing") {
+			activityWatchMediaLastStatus.value = "playing";
+			activityWatchMediaLastStartDuration.value =
 				currentSong.value.skipDuration + getTimeElapsed();
 		}
 
 		if (
-			activityWatchVideoLastYouTubeId.value !==
+			activityWatchMediaLastMediaSource.value !==
 			currentSong.value.mediaSource
 		) {
-			activityWatchVideoLastYouTubeId.value =
+			activityWatchMediaLastMediaSource.value =
 				currentSong.value.mediaSource;
-			activityWatchVideoLastStartDuration.value =
+			activityWatchMediaLastStartDuration.value =
 				currentSong.value.skipDuration + getTimeElapsed();
 		}
 
@@ -1082,29 +1082,38 @@ const sendActivityWatchVideoData = () => {
 			muted: muted.value,
 			volume: volumeSliderValue.value,
 			startedDuration:
-				activityWatchVideoLastStartDuration.value <= 0
+				activityWatchMediaLastStartDuration.value <= 0
 					? 0
 					: Math.floor(
-							activityWatchVideoLastStartDuration.value / 1000
+							activityWatchMediaLastStartDuration.value / 1000
 					  ),
 			source: `station#${station.value.name}`,
 			hostname: window.location.hostname,
-			playerState:
+			experimentalChangableListenMode:
+				experimentalChangableListenMode.value,
+			playerState: "",
+			playbackRate: -1
+		};
+
+		if (currentSongMediaType.value === "youtube") {
+			videoData.playerState =
 				experimentalChangableListenMode.value === "participate"
 					? "none"
 					: Object.keys(window.YT.PlayerState).find(
 							key =>
 								window.YT.PlayerState[key] ===
 								youtubePlayer.value.getPlayerState()
-					  ),
-			playbackRate: playbackRate.value,
-			experimentalChangableListenMode:
-				experimentalChangableListenMode.value
-		};
+					  );
+
+			videoData.playbackRate = playbackRate.value;
+		} else {
+			delete videoData.playerState;
+			delete videoData.playbackRate;
+		}
 
-		aw.sendVideoData(videoData);
+		aw.sendMediaData(videoData);
 	} else {
-		activityWatchVideoLastStatus.value = "not_playing";
+		activityWatchMediaLastStatus.value = "not_playing";
 	}
 };
 
@@ -1163,8 +1172,8 @@ onMounted(async () => {
 	stationIdentifier.value = route.params.id;
 
 	window.stationInterval = 0;
-	activityWatchVideoDataInterval.value = setInterval(() => {
-		sendActivityWatchVideoData();
+	activityWatchMediaDataInterval.value = setInterval(() => {
+		sendActivityWatchMediaData();
 	}, 1000);
 	reportStationStateInterval.value = setInterval(() => {
 		socket.dispatch(
@@ -1851,7 +1860,7 @@ onBeforeUnmount(() => {
 
 	mediaModalWatcher.value(); // removes the watcher
 
-	clearInterval(activityWatchVideoDataInterval.value);
+	clearInterval(activityWatchMediaDataInterval.value);
 	clearTimeout(window.stationNextSongTimeout);
 	clearTimeout(persistentToastCheckerInterval.value);
 	clearInterval(reportStationStateInterval.value);