Format/slightly modernize the JS (#345)
* add basic JS tooling * fix accidental uses of global variables * auto-format * add and fix a couple more standard lint rules * remove useless return false from settimeout callbacks * document JS contributing * fix whitespace in package.json * add JS stuff to codespell skiplist * codespell take two * update github action and add comments about duplicated logic
This commit is contained in:
parent
700a8cb54a
commit
39902cb1c6
|
@ -0,0 +1,17 @@
|
||||||
|
'use strict';
|
||||||
|
module.exports = {
|
||||||
|
extends: ['eslint:recommended', 'eslint-config-prettier'],
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
strict: ['error', 'global'],
|
||||||
|
'no-unused-vars': ['error', { vars: 'local' }],
|
||||||
|
eqeqeq: ['error', 'always', { null: 'ignore' }],
|
||||||
|
curly: ['error', 'multi-line'],
|
||||||
|
'no-var': 'error',
|
||||||
|
},
|
||||||
|
};
|
|
@ -6,11 +6,13 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-python@v2
|
- uses: actions/setup-python@v2
|
||||||
|
# note: this logic is duplicated in the `validate` function in ./deploy.sh
|
||||||
|
# if you update this file, you should update that as well
|
||||||
- run: pip install --upgrade pip wheel
|
- run: pip install --upgrade pip wheel
|
||||||
- run: pip install bandit black codespell flake8 flake8-bugbear
|
- run: pip install bandit black codespell flake8 flake8-bugbear
|
||||||
flake8-comprehensions isort
|
flake8-comprehensions isort
|
||||||
- run: black --check --diff --line-length 79 .
|
- run: black --check --diff --line-length 79 .
|
||||||
- run: codespell
|
- run: codespell --skip="./.git,./package.json,./package-lock.json,./node_modules"
|
||||||
- run: flake8 . --count --max-complexity=10 --max-line-length=79
|
- run: flake8 . --count --max-complexity=10 --max-line-length=79
|
||||||
--show-source --statistics
|
--show-source --statistics
|
||||||
- run: isort --check-only --line-length 79 --profile black .
|
- run: isort --check-only --line-length 79 --profile black .
|
||||||
|
|
|
@ -5,4 +5,7 @@ __pycache__
|
||||||
db.sqlite3
|
db.sqlite3
|
||||||
|
|
||||||
# vscode custom conf
|
# vscode custom conf
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
|
# JavaScript stuff
|
||||||
|
node_modules
|
||||||
|
|
|
@ -76,6 +76,10 @@ Do you see anything on the roadmap that you would like to take a closer look at
|
||||||
|
|
||||||
To fix a bug or implement a feature, fork the repository and make all changes to the testing branch. When ready, create a pull request.
|
To fix a bug or implement a feature, fork the repository and make all changes to the testing branch. When ready, create a pull request.
|
||||||
|
|
||||||
|
## Making changes to the JavaScript
|
||||||
|
|
||||||
|
The JavaScript does not require any build step; you just edit the files directly. However, there is config for eslint and prettier (a linter and formatter respectively); their use is recommended but not required. To use them, install `node`, run `npm i` from the root directory of this repository to install dependencies, then run `npm run lint` and `npm run format` to run eslint and prettier respectively.
|
||||||
|
|
||||||
## Releases
|
## Releases
|
||||||
|
|
||||||
There are three different docker tags:
|
There are three different docker tags:
|
||||||
|
|
|
@ -82,10 +82,12 @@ function validate {
|
||||||
|
|
||||||
echo "run validate on $check_path"
|
echo "run validate on $check_path"
|
||||||
|
|
||||||
|
# note: this logic is duplicated in the `./github/workflows/lint_python.yml` config
|
||||||
|
# if you update this file, you should update that as well
|
||||||
echo "running black"
|
echo "running black"
|
||||||
black --diff --color --check -l 79 "$check_path"
|
black --diff --color --check -l 79 "$check_path"
|
||||||
echo "running codespell"
|
echo "running codespell"
|
||||||
codespell --skip="./.git" "$check_path"
|
codespell --skip="./.git,./package.json,./package-lock.json,./node_modules" "$check_path"
|
||||||
echo "running flake8"
|
echo "running flake8"
|
||||||
flake8 "$check_path" --count --max-complexity=10 --max-line-length=79 \
|
flake8 "$check_path" --count --max-complexity=10 --max-line-length=79 \
|
||||||
--show-source --statistics
|
--show-source --statistics
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"lint": "eslint 'tubearchivist/static/**/*.js'",
|
||||||
|
"format": "prettier --write 'tubearchivist/static/**/*.js'"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^8.26.0",
|
||||||
|
"prettier": "^2.7.1",
|
||||||
|
"eslint-config-prettier": "^8.5.0"
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"singleQuote": true,
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"printWidth": 100
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,148 +1,157 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/* global cast chrome getVideoPlayerVideoId postVideoProgress setProgressBar getVideoPlayer getVideoPlayerWatchStatus watchedThreshold isWatched getVideoData getURL getVideoPlayerCurrentTime */
|
||||||
|
|
||||||
function initializeCastApi() {
|
function initializeCastApi() {
|
||||||
cast.framework.CastContext.getInstance().setOptions({
|
cast.framework.CastContext.getInstance().setOptions({
|
||||||
receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID, // Use built in receiver app on cast device, see https://developers.google.com/cast/docs/styled_receiver if you want to be able to add a theme, splash screen or watermark. Has a $5 one time fee.
|
receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID, // Use built in receiver app on cast device, see https://developers.google.com/cast/docs/styled_receiver if you want to be able to add a theme, splash screen or watermark. Has a $5 one time fee.
|
||||||
autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED
|
autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED,
|
||||||
});
|
});
|
||||||
|
|
||||||
var player = new cast.framework.RemotePlayer();
|
let player = new cast.framework.RemotePlayer();
|
||||||
var playerController = new cast.framework.RemotePlayerController(player);
|
let playerController = new cast.framework.RemotePlayerController(player);
|
||||||
|
|
||||||
// Add event listerner to check if a connection to a cast device is initiated
|
// Add event listerner to check if a connection to a cast device is initiated
|
||||||
playerController.addEventListener(
|
playerController.addEventListener(
|
||||||
cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED, function() {
|
cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
|
||||||
castConnectionChange(player)
|
function () {
|
||||||
}
|
castConnectionChange(player);
|
||||||
);
|
}
|
||||||
playerController.addEventListener(
|
);
|
||||||
cast.framework.RemotePlayerEventType.CURRENT_TIME_CHANGED, function() {
|
playerController.addEventListener(
|
||||||
castVideoProgress(player)
|
cast.framework.RemotePlayerEventType.CURRENT_TIME_CHANGED,
|
||||||
}
|
function () {
|
||||||
);
|
castVideoProgress(player);
|
||||||
playerController.addEventListener(
|
}
|
||||||
cast.framework.RemotePlayerEventType.IS_PAUSED_CHANGED, function() {
|
);
|
||||||
castVideoPaused(player)
|
playerController.addEventListener(
|
||||||
}
|
cast.framework.RemotePlayerEventType.IS_PAUSED_CHANGED,
|
||||||
);
|
function () {
|
||||||
|
castVideoPaused(player);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function castConnectionChange(player) {
|
function castConnectionChange(player) {
|
||||||
// If cast connection is initialized start cast
|
// If cast connection is initialized start cast
|
||||||
if (player.isConnected) {
|
if (player.isConnected) {
|
||||||
// console.log("Cast Connected.");
|
// console.log("Cast Connected.");
|
||||||
castStart();
|
castStart();
|
||||||
} else if (!player.isConnected) {
|
} else if (!player.isConnected) {
|
||||||
// console.log("Cast Disconnected.");
|
// console.log("Cast Disconnected.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function castVideoProgress(player) {
|
function castVideoProgress(player) {
|
||||||
var videoId = getVideoPlayerVideoId();
|
let videoId = getVideoPlayerVideoId();
|
||||||
if (player.mediaInfo.contentId.includes(videoId)) {
|
if (player.mediaInfo.contentId.includes(videoId)) {
|
||||||
var currentTime = player.currentTime;
|
let currentTime = player.currentTime;
|
||||||
var duration = player.duration;
|
let duration = player.duration;
|
||||||
if ((currentTime % 10) <= 1.0 && currentTime != 0 && duration != 0) { // Check progress every 10 seconds or else progress is checked a few times a second
|
if (currentTime % 10 <= 1.0 && currentTime !== 0 && duration !== 0) {
|
||||||
postVideoProgress(videoId, currentTime);
|
// Check progress every 10 seconds or else progress is checked a few times a second
|
||||||
setProgressBar(videoId, currentTime, duration);
|
postVideoProgress(videoId, currentTime);
|
||||||
if (!getVideoPlayerWatchStatus()) { // Check if video is already marked as watched
|
setProgressBar(videoId, currentTime, duration);
|
||||||
if (watchedThreshold(currentTime, duration)) {
|
if (!getVideoPlayerWatchStatus()) {
|
||||||
isWatched(videoId);
|
// Check if video is already marked as watched
|
||||||
}
|
if (watchedThreshold(currentTime, duration)) {
|
||||||
}
|
isWatched(videoId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function castVideoPaused(player) {
|
function castVideoPaused(player) {
|
||||||
var videoId = getVideoPlayerVideoId();
|
let videoId = getVideoPlayerVideoId();
|
||||||
var currentTime = player.currentTime;
|
let currentTime = player.currentTime;
|
||||||
var duration = player.duration;
|
let duration = player.duration;
|
||||||
if (player.mediaInfo != null) {
|
if (player.mediaInfo != null) {
|
||||||
if (player.mediaInfo.contentId.includes(videoId)) {
|
if (player.mediaInfo.contentId.includes(videoId)) {
|
||||||
if (currentTime != 0 && duration != 0) {
|
if (currentTime !== 0 && duration !== 0) {
|
||||||
postVideoProgress(videoId, currentTime);
|
postVideoProgress(videoId, currentTime);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function castStart() {
|
function castStart() {
|
||||||
var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
|
let castSession = cast.framework.CastContext.getInstance().getCurrentSession();
|
||||||
// Check if there is already media playing on the cast target to prevent recasting on page reload or switching to another video page
|
// Check if there is already media playing on the cast target to prevent recasting on page reload or switching to another video page
|
||||||
if (!castSession.getMediaSession()) {
|
if (!castSession.getMediaSession()) {
|
||||||
var videoId = getVideoPlayerVideoId();
|
let videoId = getVideoPlayerVideoId();
|
||||||
var videoData = getVideoData(videoId);
|
let videoData = getVideoData(videoId);
|
||||||
var contentId = getURL() + videoData.data.media_url;
|
let contentId = getURL() + videoData.data.media_url;
|
||||||
var contentTitle = videoData.data.title;
|
let contentTitle = videoData.data.title;
|
||||||
var contentImage = getURL() + videoData.data.vid_thumb_url;
|
let contentImage = getURL() + videoData.data.vid_thumb_url;
|
||||||
|
|
||||||
contentType = 'video/mp4'; // Set content type, only videos right now so it is hard coded
|
let contentType = 'video/mp4'; // Set content type, only videos right now so it is hard coded
|
||||||
contentCurrentTime = getVideoPlayerCurrentTime(); // Get video's current position
|
let contentCurrentTime = getVideoPlayerCurrentTime(); // Get video's current position
|
||||||
contentActiveSubtitle = [];
|
let contentActiveSubtitle = [];
|
||||||
// Check if a subtitle is turned on.
|
// Check if a subtitle is turned on.
|
||||||
for (var i = 0; i < getVideoPlayer().textTracks.length; i++) {
|
for (let i = 0; i < getVideoPlayer().textTracks.length; i++) {
|
||||||
if (getVideoPlayer().textTracks[i].mode == "showing") {
|
if (getVideoPlayer().textTracks[i].mode === 'showing') {
|
||||||
contentActiveSubtitle =[i + 1];
|
contentActiveSubtitle = [i + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
contentSubtitles = [];
|
let contentSubtitles = [];
|
||||||
var videoSubtitles = videoData.data.subtitles; // Array of subtitles
|
let videoSubtitles = videoData.data.subtitles; // Array of subtitles
|
||||||
if (typeof(videoSubtitles) != 'undefined' && videoData.config.downloads.subtitle) {
|
if (typeof videoSubtitles !== 'undefined' && videoData.config.downloads.subtitle) {
|
||||||
for (var i = 0; i < videoSubtitles.length; i++) {
|
for (let i = 0; i < videoSubtitles.length; i++) {
|
||||||
subtitle = new chrome.cast.media.Track(i, chrome.cast.media.TrackType.TEXT);
|
let subtitle = new chrome.cast.media.Track(i, chrome.cast.media.TrackType.TEXT);
|
||||||
subtitle.trackContentId = videoSubtitles[i].media_url;
|
subtitle.trackContentId = videoSubtitles[i].media_url;
|
||||||
subtitle.trackContentType = 'text/vtt';
|
subtitle.trackContentType = 'text/vtt';
|
||||||
subtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
|
subtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
|
||||||
subtitle.name = videoSubtitles[i].name;
|
subtitle.name = videoSubtitles[i].name;
|
||||||
subtitle.language = videoSubtitles[i].lang;
|
subtitle.language = videoSubtitles[i].lang;
|
||||||
subtitle.customData = null;
|
subtitle.customData = null;
|
||||||
contentSubtitles.push(subtitle);
|
contentSubtitles.push(subtitle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaInfo = new chrome.cast.media.MediaInfo(contentId, contentType); // Create MediaInfo var that contains url and content type
|
let mediaInfo = new chrome.cast.media.MediaInfo(contentId, contentType); // Create MediaInfo var that contains url and content type
|
||||||
// mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED; // Set type of stream, BUFFERED, LIVE, OTHER
|
// mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED; // Set type of stream, BUFFERED, LIVE, OTHER
|
||||||
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata(); // Create metadata var and add it to MediaInfo
|
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata(); // Create metadata var and add it to MediaInfo
|
||||||
mediaInfo.metadata.title = contentTitle.replace("&", "&"); // Set the video title
|
mediaInfo.metadata.title = contentTitle.replace('&', '&'); // Set the video title
|
||||||
mediaInfo.metadata.images = [new chrome.cast.Image(contentImage)]; // Set the video thumbnail
|
mediaInfo.metadata.images = [new chrome.cast.Image(contentImage)]; // Set the video thumbnail
|
||||||
// mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
|
// mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
|
||||||
mediaInfo.tracks = contentSubtitles;
|
mediaInfo.tracks = contentSubtitles;
|
||||||
|
|
||||||
var request = new chrome.cast.media.LoadRequest(mediaInfo); // Create request with the previously set MediaInfo.
|
let request = new chrome.cast.media.LoadRequest(mediaInfo); // Create request with the previously set MediaInfo.
|
||||||
// request.queueData = new chrome.cast.media.QueueData(); // See https://developers.google.com/cast/docs/reference/web_sender/chrome.cast.media.QueueData for playlist support.
|
// request.queueData = new chrome.cast.media.QueueData(); // See https://developers.google.com/cast/docs/reference/web_sender/chrome.cast.media.QueueData for playlist support.
|
||||||
request.currentTime = shiftCurrentTime(contentCurrentTime); // Set video start position based on the browser video position
|
request.currentTime = shiftCurrentTime(contentCurrentTime); // Set video start position based on the browser video position
|
||||||
request.activeTrackIds = contentActiveSubtitle; // Set active subtitle based on video player
|
request.activeTrackIds = contentActiveSubtitle; // Set active subtitle based on video player
|
||||||
// request.autoplay = false; // Set content to auto play, true by default
|
// request.autoplay = false; // Set content to auto play, true by default
|
||||||
castSession.loadMedia(request).then(
|
castSession.loadMedia(request).then(
|
||||||
function() {
|
function () {
|
||||||
castSuccessful();
|
castSuccessful();
|
||||||
},
|
},
|
||||||
function() {
|
function (error) {
|
||||||
castFailed(errorCode);
|
castFailed(error.code);
|
||||||
}
|
}
|
||||||
); // Send request to cast device
|
); // Send request to cast device
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function shiftCurrentTime(contentCurrentTime) { // Shift media back 3 seconds to prevent missing some of the content
|
function shiftCurrentTime(contentCurrentTime) {
|
||||||
if (contentCurrentTime > 5) {
|
// Shift media back 3 seconds to prevent missing some of the content
|
||||||
return(contentCurrentTime - 3);
|
if (contentCurrentTime > 5) {
|
||||||
} else {
|
return contentCurrentTime - 3;
|
||||||
return(0);
|
} else {
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function castSuccessful() {
|
function castSuccessful() {
|
||||||
// console.log('Cast Successful.');
|
// console.log('Cast Successful.');
|
||||||
getVideoPlayer().pause(); // Pause browser video on successful cast
|
getVideoPlayer().pause(); // Pause browser video on successful cast
|
||||||
}
|
}
|
||||||
|
|
||||||
function castFailed(errorCode) {
|
function castFailed(errorCode) {
|
||||||
console.log('Error code: ' + errorCode);
|
console.log('Error code: ' + errorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
window['__onGCastApiAvailable'] = function(isAvailable) {
|
window['__onGCastApiAvailable'] = function (isAvailable) {
|
||||||
if (isAvailable) {
|
if (isAvailable) {
|
||||||
initializeCastApi();
|
initializeCastApi();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,106 +1,110 @@
|
||||||
/**
|
/**
|
||||||
* Handle multi channel notifications
|
* Handle multi channel notifications
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
checkMessages()
|
'use strict';
|
||||||
|
|
||||||
|
checkMessages();
|
||||||
|
|
||||||
// page map to notification status
|
// page map to notification status
|
||||||
const messageTypes = {
|
const messageTypes = {
|
||||||
"download": ["message:download", "message:add", "message:rescan", "message:playlistscan"],
|
download: ['message:download', 'message:add', 'message:rescan', 'message:playlistscan'],
|
||||||
"channel": ["message:subchannel"],
|
channel: ['message:subchannel'],
|
||||||
"channel_id": ["message:playlistscan"],
|
channel_id: ['message:playlistscan'],
|
||||||
"playlist": ["message:subplaylist"],
|
playlist: ['message:subplaylist'],
|
||||||
"setting": ["message:setting"]
|
setting: ['message:setting'],
|
||||||
}
|
};
|
||||||
|
|
||||||
// start to look for messages
|
// start to look for messages
|
||||||
function checkMessages() {
|
function checkMessages() {
|
||||||
var notifications = document.getElementById("notifications");
|
let notifications = document.getElementById('notifications');
|
||||||
if (notifications) {
|
if (notifications) {
|
||||||
var dataOrigin = notifications.getAttribute("data");
|
let dataOrigin = notifications.getAttribute('data');
|
||||||
getMessages(dataOrigin);
|
getMessages(dataOrigin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get messages for page on timer
|
// get messages for page on timer
|
||||||
function getMessages(dataOrigin) {
|
function getMessages(dataOrigin) {
|
||||||
fetch('/progress/').then(response => {
|
fetch('/progress/')
|
||||||
return response.json();
|
.then(response => {
|
||||||
}).then(responseData => {
|
return response.json();
|
||||||
var messages = buildMessage(responseData, dataOrigin);
|
})
|
||||||
if (messages.length > 0) {
|
.then(responseData => {
|
||||||
// restart itself
|
let messages = buildMessage(responseData, dataOrigin);
|
||||||
setTimeout(function() {
|
if (messages.length > 0) {
|
||||||
getMessages(dataOrigin);
|
// restart itself
|
||||||
}, 3000);
|
setTimeout(function () {
|
||||||
};
|
getMessages(dataOrigin);
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// make div for all messages, return relevant
|
// make div for all messages, return relevant
|
||||||
function buildMessage(responseData, dataOrigin) {
|
function buildMessage(responseData, dataOrigin) {
|
||||||
// filter relevan messages
|
// filter relevan messages
|
||||||
var allMessages = responseData["messages"];
|
let allMessages = responseData['messages'];
|
||||||
var messages = allMessages.filter(function(value) {
|
let messages = allMessages.filter(function (value) {
|
||||||
return messageTypes[dataOrigin].includes(value["status"])
|
return messageTypes[dataOrigin].includes(value['status']);
|
||||||
}, dataOrigin);
|
}, dataOrigin);
|
||||||
// build divs
|
// build divs
|
||||||
var notificationDiv = document.getElementById("notifications");
|
let notificationDiv = document.getElementById('notifications');
|
||||||
var nots = notificationDiv.childElementCount;
|
let nots = notificationDiv.childElementCount;
|
||||||
notificationDiv.innerHTML = "";
|
notificationDiv.innerHTML = '';
|
||||||
for (let i = 0; i < messages.length; i++) {
|
for (let i = 0; i < messages.length; i++) {
|
||||||
var messageData = messages[i];
|
let messageData = messages[i];
|
||||||
var messageStatus = messageData["status"];
|
let messageStatus = messageData['status'];
|
||||||
var messageBox = document.createElement("div");
|
let messageBox = document.createElement('div');
|
||||||
var title = document.createElement("h3");
|
let title = document.createElement('h3');
|
||||||
title.innerHTML = messageData["title"];
|
title.innerHTML = messageData['title'];
|
||||||
var message = document.createElement("p");
|
let message = document.createElement('p');
|
||||||
message.innerHTML = messageData["message"];
|
message.innerHTML = messageData['message'];
|
||||||
messageBox.appendChild(title);
|
messageBox.appendChild(title);
|
||||||
messageBox.appendChild(message);
|
messageBox.appendChild(message);
|
||||||
messageBox.classList.add(messageData["level"], "notification");
|
messageBox.classList.add(messageData['level'], 'notification');
|
||||||
notificationDiv.appendChild(messageBox);
|
notificationDiv.appendChild(messageBox);
|
||||||
if (messageStatus === "message:download") {
|
if (messageStatus === 'message:download') {
|
||||||
checkDownloadIcons();
|
checkDownloadIcons();
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
// reload page when no more notifications
|
// reload page when no more notifications
|
||||||
if (nots > 0 && messages.length === 0) {
|
if (nots > 0 && messages.length === 0) {
|
||||||
location.reload();
|
location.reload();
|
||||||
};
|
}
|
||||||
return messages
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if download icons are needed
|
// check if download icons are needed
|
||||||
function checkDownloadIcons() {
|
function checkDownloadIcons() {
|
||||||
var iconBox = document.getElementById("downloadControl");
|
let iconBox = document.getElementById('downloadControl');
|
||||||
if (iconBox.childElementCount === 0) {
|
if (iconBox.childElementCount === 0) {
|
||||||
var downloadIcons = buildDownloadIcons();
|
let downloadIcons = buildDownloadIcons();
|
||||||
iconBox.appendChild(downloadIcons);
|
iconBox.appendChild(downloadIcons);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add dl control icons
|
// add dl control icons
|
||||||
function buildDownloadIcons() {
|
function buildDownloadIcons() {
|
||||||
var downloadIcons = document.createElement('div');
|
let downloadIcons = document.createElement('div');
|
||||||
downloadIcons.classList = 'dl-control-icons';
|
downloadIcons.classList = 'dl-control-icons';
|
||||||
// stop icon
|
// stop icon
|
||||||
var stopIcon = document.createElement('img');
|
let stopIcon = document.createElement('img');
|
||||||
stopIcon.setAttribute('id', "stop-icon");
|
stopIcon.setAttribute('id', 'stop-icon');
|
||||||
stopIcon.setAttribute('title', "Stop Download Queue");
|
stopIcon.setAttribute('title', 'Stop Download Queue');
|
||||||
stopIcon.setAttribute('src', "/static/img/icon-stop.svg");
|
stopIcon.setAttribute('src', '/static/img/icon-stop.svg');
|
||||||
stopIcon.setAttribute('alt', "stop icon");
|
stopIcon.setAttribute('alt', 'stop icon');
|
||||||
stopIcon.setAttribute('onclick', 'stopQueue()');
|
stopIcon.setAttribute('onclick', 'stopQueue()');
|
||||||
// kill icon
|
// kill icon
|
||||||
var killIcon = document.createElement('img');
|
let killIcon = document.createElement('img');
|
||||||
killIcon.setAttribute('id', "kill-icon");
|
killIcon.setAttribute('id', 'kill-icon');
|
||||||
killIcon.setAttribute('title', "Kill Download Queue");
|
killIcon.setAttribute('title', 'Kill Download Queue');
|
||||||
killIcon.setAttribute('src', "/static/img/icon-close.svg");
|
killIcon.setAttribute('src', '/static/img/icon-close.svg');
|
||||||
killIcon.setAttribute('alt', "kill icon");
|
killIcon.setAttribute('alt', 'kill icon');
|
||||||
killIcon.setAttribute('onclick', 'killQueue()');
|
killIcon.setAttribute('onclick', 'killQueue()');
|
||||||
// stich together
|
// stich together
|
||||||
downloadIcons.appendChild(stopIcon);
|
downloadIcons.appendChild(stopIcon);
|
||||||
downloadIcons.appendChild(killIcon);
|
downloadIcons.appendChild(killIcon);
|
||||||
return downloadIcons
|
return downloadIcons;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue