Skip to content

Commit

Permalink
feat: mark as watched button in feed (#3746)
Browse files Browse the repository at this point in the history
* feat: add mark as watched/unwatched button

* fix: remove from trending page and hide if watch history is diabled

remove the button from trending page because it only works in feed page.

* fix: missing thumbnail url in watch_history  when using mark as watched

* fix: missing uploadername in watch_history when using mark as watched

* refactor: make mark as watched consistent with other app elements

* refactor: simplify setting "watched" property for videos

---------

Co-authored-by: Bnyro <[email protected]>
  • Loading branch information
HiImKobeAnd and Bnyro authored Jan 7, 2025
1 parent 56bcc1b commit 676dbef
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 3 deletions.
11 changes: 10 additions & 1 deletion src/components/FeedPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@

<LoadingIndicatorPage :show-content="videosStore != null" class="video-grid">
<template v-for="video in filteredVideos" :key="video.url">
<VideoItem v-if="shouldShowVideo(video)" :is-feed="true" :item="video" />
<VideoItem v-if="shouldShowVideo(video)" :is-feed="true" :item="video" @update:watched="onUpdateWatched" />
</template>
</LoadingIndicatorPage>
</template>
Expand Down Expand Up @@ -140,6 +140,15 @@ export default {
this.loadMoreVideos();
}
},
onUpdateWatched(urls = null) {
if (urls === null) {
if (this.videos.length > 0) this.updateWatched(this.videos);
return;
}
const subset = this.videos.filter(({ url }) => urls.includes(url));
if (subset.length > 0) this.updateWatched(subset);
},
shouldShowVideo(video) {
switch (this.selectedFilter.toLowerCase()) {
case "shorts":
Expand Down
48 changes: 47 additions & 1 deletion src/components/VideoItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,18 @@
>
<i class="i-fa6-solid:circle-minus" />
</button>
<button
v-if="showMarkOnWatched && isFeed"
ref="watchButton"
@click="toggleWatched(item.url.substr(-11))"
>
<i
v-if="item.watched && item.currentTime > item.duration * 0.9"
:title="$t('actions.mark_as_unwatched')"
class="i-fa6-solid:eye-slash"
/>
<i v-else :title="$t('actions.mark_as_watched')" class="i-fa6-solid:eye" />
</button>
<ConfirmModal
v-if="showConfirmRemove"
:message="$t('actions.delete_playlist_video_confirm')"
Expand Down Expand Up @@ -176,13 +188,14 @@ export default {
preferListen: { type: Boolean, default: false },
admin: { type: Boolean, default: false },
},
emits: ["remove"],
emits: ["update:watched", "remove"],
data() {
return {
showPlaylistModal: false,
showShareModal: false,
showVideo: true,
showConfirmRemove: false,
showMarkOnWatched: false,
};
},
computed: {
Expand All @@ -195,6 +208,7 @@ export default {
},
mounted() {
this.shouldShowVideo();
this.shouldShowMarkOnWatched();
},
methods: {
removeVideo() {
Expand All @@ -217,6 +231,38 @@ export default {
}
};
},
shouldShowMarkOnWatched() {
this.showMarkOnWatched = this.getPreferenceBoolean("watchHistory", false);
},
toggleWatched(videoId) {
if (window.db) {
var tx = window.db.transaction("watch_history", "readwrite");
var store = tx.objectStore("watch_history");
var instance = this;
var request = store.get(videoId);
request.onsuccess = function (event) {
var video = event.target.result;
if (video) {
video.watchedAt = Date.now();
} else {
video = {
videoId: videoId,
title: instance.item.title,
duration: instance.item.duration,
thumbnail: instance.item.thumbnail,
uploaderUrl: instance.item.uploaderUrl,
uploaderName: instance.item.uploaderName,
watchedAt: Date.now(),
};
}
video.currentTime =
instance.item.currentTime < instance.item.duration * 0.9 ? instance.item.duration : 0;
store.put(video);
instance.$emit("update:watched", [instance.item.url]);
instance.shouldShowVideo();
};
}
},
},
};
</script>
Expand Down
2 changes: 2 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@
"show_chapters": "Chapters",
"store_search_history": "Store Search History",
"hide_watched": "Hide watched videos in the feed",
"mark_as_watched": "Mark as Watched",
"mark_as_unwatched": "Mark as Unwatched",
"documentation": "Documentation",
"status_page": "Status",
"source_code": "Source code",
Expand Down
2 changes: 1 addition & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ const mixin = {
var request = store.get(video.url.substr(-11));
request.onsuccess = function (event) {
if (event.target.result) {
video.watched = true;
video.watched = event.target.result.currentTime != 0;
video.currentTime = event.target.result.currentTime;
}
};
Expand Down

0 comments on commit 676dbef

Please sign in to comment.