Implemeneted favourited system
This commit is contained in:
Generated
+12
-2
@@ -1,16 +1,17 @@
|
||||
{
|
||||
"name": "Materialious",
|
||||
"version": "1.12.0",
|
||||
"version": "1.12.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "Materialious",
|
||||
"version": "1.12.0",
|
||||
"version": "1.12.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@capacitor-community/electron": "^5.0.0",
|
||||
"bgutils-js": "^3.2.0",
|
||||
"capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.9/capacitor-nodejs.tgz",
|
||||
"chokidar": "~5.0.0",
|
||||
"electron-is-dev": "~2.0.0",
|
||||
"electron-serve": "~3.0.0",
|
||||
@@ -1885,6 +1886,15 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/capacitor-nodejs": {
|
||||
"version": "1.0.0-beta.9",
|
||||
"resolved": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.9/capacitor-nodejs.tgz",
|
||||
"integrity": "sha512-4EU/QBolfuyHiMtwd1nxZ4wsK243tGE4VttKvVBG+x1yQuK9EIlEf3lbRjFXfjrJMTZNCqaP6glmdfj9Zo7KVg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@capacitor/core": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"dependencies": {
|
||||
"@capacitor-community/electron": "^5.0.0",
|
||||
"bgutils-js": "^3.2.0",
|
||||
"capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.9/capacitor-nodejs.tgz",
|
||||
"chokidar": "~5.0.0",
|
||||
"electron-is-dev": "~2.0.0",
|
||||
"electron-serve": "~3.0.0",
|
||||
@@ -43,4 +44,4 @@
|
||||
"capacitor",
|
||||
"electron"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const CapacitorNodejs = require('../../../node_modules/capacitor-nodejs/electron/dist/plugin.js');
|
||||
|
||||
module.exports = {
|
||||
CapacitorNodejs,
|
||||
}
|
||||
Generated
+9
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "materialious",
|
||||
"version": "1.12.0",
|
||||
"version": "1.12.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "materialious",
|
||||
"version": "1.12.0",
|
||||
"version": "1.12.3",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@capacitor-community/electron": "^5.0.1",
|
||||
@@ -25,6 +25,7 @@
|
||||
"bgutils-js": "^3.2.0",
|
||||
"capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.9/capacitor-nodejs.tgz",
|
||||
"dayjs": "^1.11.19",
|
||||
"dexie": "^4.2.1",
|
||||
"fuse.js": "^7.0.0",
|
||||
"googlevideo": "^4.0.4",
|
||||
"he": "^1.2.0",
|
||||
@@ -5669,6 +5670,12 @@
|
||||
"integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dexie": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/dexie/-/dexie-4.2.1.tgz",
|
||||
"integrity": "sha512-Ckej0NS6jxQ4Po3OrSQBFddayRhTCic2DoCAG5zacOfOVB9P2Q5Xc5uL/nVa7ZVs+HdMnvUPzLFCB/JwpB6Csg==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/dezalgo": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
"bgutils-js": "^3.2.0",
|
||||
"capacitor-nodejs": "https://github.com/hampoelz/capacitor-nodejs/releases/download/v1.0.0-beta.9/capacitor-nodejs.tgz",
|
||||
"dayjs": "^1.11.19",
|
||||
"dexie": "^4.2.1",
|
||||
"fuse.js": "^7.0.0",
|
||||
"googlevideo": "^4.0.4",
|
||||
"he": "^1.2.0",
|
||||
@@ -73,4 +74,4 @@
|
||||
"svelte-infinite-loading": "^1.4.0",
|
||||
"youtubei.js": "^16.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ export interface VideoBase {
|
||||
lengthSeconds: number;
|
||||
viewCountText: string;
|
||||
viewCount?: number;
|
||||
// Means it was given preference in rankings due to
|
||||
// a users settings
|
||||
promotedBy?: 'favourited';
|
||||
}
|
||||
|
||||
export interface ResolvedUrl {
|
||||
@@ -205,6 +208,9 @@ export interface PlaylistPageVideo extends Omit<PlaylistVideo, 'type'> {
|
||||
indexId: string;
|
||||
authorId: string;
|
||||
viewCount: number;
|
||||
// Means it was given preference in rankings due to
|
||||
// a users settings
|
||||
promotedBy?: 'favourited';
|
||||
}
|
||||
|
||||
export interface ChannelContentVideos {
|
||||
|
||||
@@ -229,6 +229,10 @@
|
||||
<p>{video.author}</p>
|
||||
{/if}
|
||||
|
||||
{#if video.promotedBy === 'favourited'}
|
||||
<i>star</i>
|
||||
{/if}
|
||||
|
||||
{#if !('publishedText' in video) && 'viewCountText' in video}
|
||||
•
|
||||
{video.viewCountText ?? cleanNumber(video.viewCount ?? 0)}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
import { truncate } from '$lib/misc';
|
||||
import { authStore, interfaceLowBandwidthMode, isAndroidTvStore } from '$lib/store';
|
||||
import { _ } from '$lib/i18n';
|
||||
import { localDb } from '$lib/dexie';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let {
|
||||
video,
|
||||
@@ -13,6 +15,16 @@
|
||||
hideSubscribe = false
|
||||
}: { video: VideoPlay; subscribed?: boolean; hideSubscribe?: boolean } = $props();
|
||||
|
||||
let favoritedChannel = $state(false);
|
||||
|
||||
const favoriteChannelItem = localDb.favouriteChannels.filter((item) => {
|
||||
return item.channelId === video.authorId;
|
||||
});
|
||||
|
||||
onMount(async () => {
|
||||
favoritedChannel = (await favoriteChannelItem.count()) > 0;
|
||||
});
|
||||
|
||||
async function toggleSubscribed() {
|
||||
if (subscribed) {
|
||||
await deleteUnsubscribe(video.authorId);
|
||||
@@ -22,6 +34,16 @@
|
||||
|
||||
subscribed = !subscribed;
|
||||
}
|
||||
|
||||
async function toggleFavourited() {
|
||||
if (favoritedChannel) {
|
||||
await favoriteChannelItem.delete();
|
||||
favoritedChannel = false;
|
||||
} else {
|
||||
await localDb.favouriteChannels.add({ channelId: video.authorId, created: new Date() });
|
||||
favoritedChannel = true;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<nav>
|
||||
@@ -56,6 +78,16 @@
|
||||
{$_('unsubscribe')}
|
||||
{/if}
|
||||
</button>
|
||||
<button
|
||||
class:inverse-surface={!favoritedChannel}
|
||||
class:border={favoritedChannel}
|
||||
onclick={toggleFavourited}
|
||||
>
|
||||
<i>star</i>
|
||||
<div class="tooltip">
|
||||
{favoritedChannel ? $_('unfavouriteChannel') : $_('favouriteChannel')}
|
||||
</div>
|
||||
</button>
|
||||
{:else}
|
||||
<button class="inverse-surface" disabled>
|
||||
{$_('subscribe')}
|
||||
|
||||
@@ -200,5 +200,7 @@
|
||||
"titleOnly": "Title only"
|
||||
}
|
||||
},
|
||||
"subscribe": "Subscribe"
|
||||
"subscribe": "Subscribe",
|
||||
"favouriteChannel": "Favourite channel",
|
||||
"unfavouriteChannel": "Unfavourite channel"
|
||||
}
|
||||
|
||||
@@ -1,10 +1,36 @@
|
||||
import { getFeed } from '$lib/api/index';
|
||||
import type { PlaylistPageVideo, Video, VideoBase } from '$lib/api/model';
|
||||
import { localDb } from '$lib/dexie';
|
||||
import { excludeDuplicateFeeds } from '$lib/misc';
|
||||
import { feedCacheStore } from '$lib/store';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
async function sortVideosByFavourites(
|
||||
videos: (VideoBase | Video | PlaylistPageVideo)[]
|
||||
): Promise<(VideoBase | Video | PlaylistPageVideo)[]> {
|
||||
const favouritedChannels = (await localDb.favouriteChannels.toArray()).map(
|
||||
(channel) => channel.channelId
|
||||
);
|
||||
|
||||
if (favouritedChannels.length === 0) {
|
||||
return videos;
|
||||
}
|
||||
|
||||
const rearrangedVideos: (VideoBase | Video | PlaylistPageVideo)[] = [];
|
||||
|
||||
videos.forEach((video) => {
|
||||
if (favouritedChannels.includes(video.authorId)) {
|
||||
video.promotedBy = 'favourited';
|
||||
rearrangedVideos.unshift(video);
|
||||
} else {
|
||||
rearrangedVideos.push(video);
|
||||
}
|
||||
});
|
||||
|
||||
return rearrangedVideos;
|
||||
}
|
||||
|
||||
export async function load() {
|
||||
let videos = get(feedCacheStore).subscription;
|
||||
|
||||
@@ -16,12 +42,16 @@ export async function load() {
|
||||
error(500, errorMessage);
|
||||
}
|
||||
|
||||
videos = [...feeds.notifications, ...feeds.videos];
|
||||
videos = await sortVideosByFavourites([...feeds.notifications, ...feeds.videos]);
|
||||
|
||||
feedCacheStore.set({ ...get(feedCacheStore), subscription: videos });
|
||||
} else {
|
||||
await getFeed(100, 1).then((feeds) => {
|
||||
const newVideos = [...feeds.notifications, ...feeds.videos, ...videos];
|
||||
await getFeed(100, 1).then(async (feeds) => {
|
||||
const newVideos = await sortVideosByFavourites([
|
||||
...feeds.notifications,
|
||||
...feeds.videos,
|
||||
...videos
|
||||
]);
|
||||
feedCacheStore.set({
|
||||
...get(feedCacheStore),
|
||||
subscription: excludeDuplicateFeeds(videos, newVideos) as (
|
||||
|
||||
Reference in New Issue
Block a user