Skip to content

Commit e79e360

Browse files
authored
Display shorts sorting percentage on button (#293)
1 parent 6f04bd1 commit e79e360

File tree

7 files changed

+89
-20
lines changed

7 files changed

+89
-20
lines changed

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# Changelog
22

3-
## v3.1.3-beta
3+
## v3.1.3
44

55
<!--Releasenotes start-->
6+
- When ignoring or only shuffling from shorts, the button will now more accurately display how long the shuffle will take.
67
- Cleaned up the popup and moved some settings to a separate menu.
7-
- Fixed a bug where a correction of database corruption would reduce the user's daily API quota.
8+
- Fixed a bug where fixing a rare database corruption issue would reduce the user's daily API quota.
89
<!--Releasenotes end-->
910

1011
## v3.1.2

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "random-youtube-video",
3-
"version": "3.1.2",
3+
"version": "3.1.3",
44
"description": "Customize, shuffle and play random videos from any YouTube channel.",
55
"scripts": {
66
"dev": "concurrently \"npm run dev:chromium\" \"npm run dev:firefox\"",

src/chromeStorage.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ export async function getUserQuotaRemainingToday() {
4242
return configSync.userQuotaRemainingToday;
4343
}
4444

45-
// -- Private --
46-
async function validateConfigSync() {
45+
export async function validateConfigSync() {
4746
const configSyncValues = await chrome.storage.sync.get();
4847

4948
// Set default values for config values that do not exist in sync storage

src/shuffleVideo.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ export async function chooseRandomVideo(channelId, firedFromPopup, progressTextE
2424
try {
2525
// While chooseRandomVideo is running, we need to keep the service worker alive
2626
// Otherwise, it will get stopped after 30 seconds and we will get an error if fetching the videos takes longer
27-
// So every 25 seconds, we send a message to the service worker to keep it alive
27+
// So every 20 seconds, we send a message to the service worker to keep it alive
2828
var keepServiceWorkerAlive = setInterval(() => {
2929
chrome.runtime.sendMessage({ command: "connectionTest" });
30-
}, 25000);
30+
}, 20000);
3131
/* c8 ignore stop */
3232

3333
// Each user has a set amount of quota they can use per day.
@@ -123,7 +123,7 @@ export async function chooseRandomVideo(channelId, firedFromPopup, progressTextE
123123

124124
let chosenVideos;
125125
var encounteredDeletedVideos;
126-
({ chosenVideos, playlistInfo, shouldUpdateDatabase, encounteredDeletedVideos } = await chooseRandomVideosFromPlaylist(playlistInfo, channelId, shouldUpdateDatabase));
126+
({ chosenVideos, playlistInfo, shouldUpdateDatabase, encounteredDeletedVideos } = await chooseRandomVideosFromPlaylist(playlistInfo, channelId, shouldUpdateDatabase, progressTextElement));
127127

128128
// Save the playlist to the database and locally
129129
playlistInfo = await handlePlaylistDatabaseUpload(playlistInfo, uploadsPlaylistId, shouldUpdateDatabase, databaseSharing, encounteredDeletedVideos);
@@ -674,7 +674,7 @@ async function isShort(videoId) {
674674
return videoIsShort;
675675
}
676676

677-
// Requests the API key from the background script
677+
// Requests an API key from the background script
678678
async function getAPIKey(useAPIKeyAtIndex = null) {
679679
const msg = {
680680
command: "getAPIKey",
@@ -701,7 +701,7 @@ async function getAPIKey(useAPIKeyAtIndex = null) {
701701
return { APIKey, isCustomKey, keyIndex };
702702
}
703703

704-
async function chooseRandomVideosFromPlaylist(playlistInfo, channelId, shouldUpdateDatabase) {
704+
async function chooseRandomVideosFromPlaylist(playlistInfo, channelId, shouldUpdateDatabase, progressTextElement) {
705705
let activeShuffleFilterOption = configSync.channelSettings[channelId]?.activeOption ?? "allVideosOption";
706706
let activeOptionValue;
707707

@@ -763,16 +763,21 @@ async function chooseRandomVideosFromPlaylist(playlistInfo, channelId, shouldUpd
763763

764764
console.log(`Choosing ${numVideosToChoose} random video(s).`);
765765

766+
// We keep track of the progress of determining the video types if there is a shorts handling filter, to display on the button
767+
let numVideosProcessed = 0;
768+
const initialTotalNumVideos = videosToShuffle.length;
769+
766770
// We use this label to break out of both the for loop and the while loop if there are no more videos after encountering a deleted video
767771
outerLoop:
768772
for (let i = 0; i < numVideosToChoose; i++) {
769773
if (videosToShuffle.length === 0) {
770-
// All available videos were chosen from, so we need to terminate the loop early
774+
// All available videos were chosen, so we need to terminate the loop early
771775
console.log(`No more videos to choose from (${numVideosToChoose - i} videos too few uploaded on channel).`);
772776
break outerLoop;
773777
}
774778

775779
randomVideo = videosToShuffle[Math.floor(Math.random() * videosToShuffle.length)];
780+
numVideosProcessed++;
776781

777782
// If the video does not exist, remove it from the playlist and choose a new one, until we find one that exists
778783
if (!await testVideoExistence(randomVideo, allVideos[randomVideo])) {
@@ -786,6 +791,7 @@ async function chooseRandomVideosFromPlaylist(playlistInfo, channelId, shouldUpd
786791
// Remove the deleted video from the videosToShuffle array and choose a new random video
787792
videosToShuffle.splice(videosToShuffle.indexOf(randomVideo), 1);
788793
randomVideo = videosToShuffle[Math.floor(Math.random() * videosToShuffle.length)];
794+
numVideosProcessed++;
789795

790796
console.log(`The chosen video does not exist anymore, so it will be removed from the database. A new random video has been chosen: ${randomVideo}`);
791797

@@ -818,8 +824,11 @@ async function chooseRandomVideosFromPlaylist(playlistInfo, channelId, shouldUpd
818824
if (playlistInfo["videos"]["unknownType"][randomVideo] !== undefined) {
819825
const videoIsShort = await isShort(randomVideo);
820826

821-
// What follows is dependent on if the video is a short or not, and the user's settings
827+
// We display either the percentage of videos processed or the percentage of videos chosen (vs. needed), whichever is higher
828+
const percentage = Math.max(Math.round(chosenVideos.length / numVideosToChoose * 100), Math.round(numVideosProcessed / initialTotalNumVideos * 100));
829+
updateProgressTextElement(progressTextElement, `\xa0Sorting: ${percentage}%`, `${percentage}%`);
822830

831+
// What follows is dependent on if the video is a short or not, and the user's settings
823832
// Case 1: !isShort && ignoreShorts => Success
824833
if (!videoIsShort && configSync.shuffleIgnoreShortsOption == "2") {
825834
// Move the video to the knownVideos subdictionary

static/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"name": "Random YouTube Video",
33
"description": "Customize, shuffle and play random videos from any YouTube channel.",
4-
"version": "3.1.2",
5-
"version_name": "3.1.3-beta",
4+
"version": "3.1.3",
5+
"version_name": "3.1.3",
66
"manifest_version": 3,
77
"content_scripts": [
88
{

test/chromeStorage.test.js

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import expect from 'expect.js';
22

3-
import { configSync, setSyncStorageValue, removeSyncStorageValue, getUserQuotaRemainingToday } from '../src/chromeStorage.js';
3+
import { configSync, setSyncStorageValue, removeSyncStorageValue, getUserQuotaRemainingToday, validateConfigSync } from '../src/chromeStorage.js';
44
import { configSyncDefaults } from '../src/config.js';
55

66
describe('chromeStorage', function () {
@@ -75,7 +75,6 @@ describe('chromeStorage', function () {
7575
});
7676

7777
context('removeSyncStorageValue()', function () {
78-
7978
it('should remove the value from the configSync object', async function () {
8079
await setSyncStorageValue("testKey4", "testValue4");
8180

@@ -86,10 +85,9 @@ describe('chromeStorage', function () {
8685

8786
expect(configSync).to.not.have.key("testKey4");
8887
});
89-
9088
});
91-
context('getUserQuotaRemainingToday()', function () {
9289

90+
context('getUserQuotaRemainingToday()', function () {
9391
it('should return the number of requests the user can still make to the Youtube API today', async function () {
9492
await setSyncStorageValue("userQuotaRemainingToday", 20);
9593

@@ -117,7 +115,69 @@ describe('chromeStorage', function () {
117115
// Check that the reset time is set to midnight
118116
expect(configSync.userQuotaResetTime).to.be(new Date(new Date().setHours(24, 0, 0, 0)).getTime());
119117
});
118+
});
119+
120+
context('validateConfigSync()', function () {
121+
context('fix incorrect settings', async function () {
122+
it('should reset the useCustomApiKeyOption if no API key is set', async function () {
123+
await setSyncStorageValue("useCustomApiKeyOption", true);
124+
await setSyncStorageValue("customYoutubeApiKey", null);
125+
126+
await validateConfigSync();
127+
128+
expect(configSync.useCustomApiKeyOption).to.be(false);
129+
});
130+
131+
it('should enable database sharing if no API key is set', async function () {
132+
await setSyncStorageValue("useCustomApiKeyOption", false);
133+
await setSyncStorageValue("databaseSharingEnabledOption", false);
134+
135+
await validateConfigSync();
136+
137+
expect(configSync.databaseSharingEnabledOption).to.be(true);
138+
});
139+
140+
it('should disable reusing the new tab if shuffling does not open a new tab', async function () {
141+
await setSyncStorageValue("shuffleOpenInNewTabOption", false);
142+
await setSyncStorageValue("shuffleReUseNewTabOption", true);
143+
144+
await validateConfigSync();
120145

146+
expect(configSync.shuffleReUseNewTabOption).to.be(false);
147+
});
148+
149+
it('should ensure valid values are set for ignoring shorts (0-2)', async function () {
150+
// Too small
151+
await setSyncStorageValue("shuffleIgnoreShortsOption", -1);
152+
153+
await validateConfigSync();
154+
155+
expect(configSync.shuffleIgnoreShortsOption).to.be(1);
156+
157+
// Too large
158+
await setSyncStorageValue("shuffleIgnoreShortsOption", 3);
159+
160+
await validateConfigSync();
161+
162+
expect(configSync.shuffleIgnoreShortsOption).to.be(1);
163+
});
164+
165+
it('should ensure valid values are set for the number of videos in a playlist', async function () {
166+
// Too small
167+
await setSyncStorageValue("shuffleNumVideosInPlaylist", 0);
168+
169+
await validateConfigSync();
170+
171+
expect(configSync.shuffleNumVideosInPlaylist).to.be(10);
172+
173+
// Too large
174+
await setSyncStorageValue("shuffleNumVideosInPlaylist", 51);
175+
176+
await validateConfigSync();
177+
178+
expect(configSync.shuffleNumVideosInPlaylist).to.be(10);
179+
});
180+
});
121181
});
122182

123183
});

0 commit comments

Comments
 (0)