const RETRY_INTERVAL_S = 5;
const PATH_EVENTS = "/{{page_names.events}}";
const PATH_PLAYER = "/{{page_names.player}}";
-const PATH_PLAYLIST = "/{{page_names.playlist}}";
const PATH_PREFIX_FILE = "/{{page_names.file}}/";
const PATH_FILES = "/{{page_names.files}}";
+function add_child_to(tag, parent, attrs={}) {
+ const el = document.createElement(tag);
+ parent.appendChild(el);
+ for (const [key, value] of Object.entries(attrs)) {
+ el[key] = value;
+ }
+ return el;
+}
+
+function add_a_to(parent, text, href) {
+ add_child_to('a', parent, {textContent: text, href: href});
+}
+
+function add_player_btn_to(parent, label, command, disabled=false) {
+ add_child_to('button', parent, {
+ textContent: label,
+ onclick: function() { player_command(command) },
+ disabled: disabled
+ });
+}
+
+function add_text_to(parent, text) {
+ const node = document.createTextNode(text);
+ parent.appendChild(node);
+ return node;
+}
+
var events_params = "";
var events_stream = null;
var event_handlers = {'ping': function(data) {}};
}
}
-function new_child_to(tag, parent, textContent='') {
- const el = document.createElement(tag);
- parent.appendChild(el);
- el.textContent = textContent;
- return el;
-}
-
async function wrapped_fetch(target, fetch_kwargs=null, verbose=false) {
if (verbose) {
console.log(`Trying to fetch ${target}, kwargs:`, fetch_kwargs);
wrapped_post(PATH_PLAYER, {command: [command]})
}
-function father_tag_links(parent_element, tags) {
+function add_tag_links_to(parent_element, tags) {
tags.forEach((tag) => {
- const a_tag = new_child_to('a', parent_element, tag);
- a_tag.href = `${PATH_FILES}?needed_tag=${encodeURIComponent(tag)}`;
- parent_element.appendChild(document.createTextNode(' '));
+ add_a_to(parent_element, tag, `${PATH_FILES}?needed_tag=${encodeURIComponent(tag)}`);
+ add_text_to(parent_element, ' ');
});
}
event_handlers.player = function(data) {
- for (const [id, text] of [
- ["a_playing", data.title],
- ["player_state", data.is_running ? (data.is_playing ? "playing:" : "paused:") : "stopped" + (data.title ? ':' : '')],
- ["btn_play", data.is_playing ? "pause" : "play"]]) {
- document.getElementById(id).textContent = text;
- }
- const span_tags = document.getElementById("playing_tags");
- span_tags.innerHTML = "";
- father_tag_links(span_tags, data.title_tags);
- for (const btn of document.getElementsByClassName("btn_if_can_play")) {
- btn.disabled = !data.can_play;
+ const div = document.getElementById("player_controls");
+ div.innerHTML = "";
+ add_player_btn_to(div, "prev", "prev", !data.can_play);
+ add_player_btn_to(div, "next", "next", !data.can_play);
+ add_player_btn_to(div, data.is_playing ? "pause" : "play", "play", !data.can_play);
+ add_text_to(div, " · ");
+ add_text_to(div, data.is_running ? (data.is_playing ? "playing:" : "paused:")
+ : "stopped" + (data.title ? ':' : ''));
+ if (data.title_digest) {
+ add_a_to(div, data.title, `${PATH_PREFIX_FILE}${data.title_digest}`);
+ add_text_to(div, " · ");
+ add_tag_links_to(div, data.title_tags);
}
- document.getElementById("a_playing").href = data.title_digest ? `${PATH_PREFIX_FILE}${data.title_digest}` : PATH_PLAYLIST ;
};
{% block script %}
· {{ macros.link_if("tags" != selected, page_names.tags) }}
· {{ macros.link_if("yt_queries" != selected, page_names.yt_queries, "queries") }}
<hr />
-<button class="btn_if_can_play" onclick="player_command('prev')">prev</button>
-<button class="btn_if_can_play" onclick="player_command('next')">next</button>
-<button id="btn_play" class="btn_if_can_play" onclick="player_command('play')">play</button>
-· <span id="player_state" /></span> <a id="a_playing"></a> <span id="playing_tags"></span>
+<div id="player_controls"></div>
<hr />
{% block body %}
{% endblock %}
{% if cond %}</a>{% endif %}
{% endmacro %}
+
+
{% macro css_sortable_table() %}
button.sorter { background-color: transparent; }
button.sorting { background-color: white; color: black; }
button.reverse { background-color: black; color: white; }
{% endmacro %}
+
+
{% macro js_manage_sortable_table(default_sort_key) %}
var sort_key = "{{default_sort_key}}";
const table = document.getElementById("sortable_table");
Array.from(document.getElementsByClassName("sortable_row")).forEach((row) => row.remove());
items_for_sortable_table.forEach((item) => {
- const tr = new_child_to('tr', table);
+ const tr = add_child_to('tr', table);
tr.classList.add("sortable_row");
populate_list_item_row(tr, item);
});
draw_sortable_table();
}
{% endmacro %}
+
const file_data = await wrapped_fetch(PATH_FILE_JSON).then((response) => response.json());
Array.from(document.getElementsByClassName("listed_tags")).forEach((row) => row.remove());
file_data.tags_showable.forEach((tag) => {
- const tr = new_child_to("tr", document.getElementById("tags_table"));
+ const tr = add_child_to("tr", document.getElementById("tags_table"));
tr.classList.add("listed_tags");
{% if allow_edit %}
- td_checkbox = new_child_to("td", tr);
+ td_checkbox = add_child_to("td", tr);
td_checkbox.classList.add("tag_checkboxes");
- const input = new_child_to("input", td_checkbox);
- input.type = "checkbox";
- input.checked = true;
- input.onclick = send_update;
+ add_child_to("input", td_checkbox, {type: "checkbox", checked: true, onclick: send_update});
{% endif %}
- const a = new_child_to("a", new_child_to("td", new_child_to("td", tr)));
- a.href = `${PATH_FILES}?needed_tag=${encodeURIComponent(tag)}`;
- a.textContent = tag;
+ add_a_to(add_child_to("td", add_child_to("td", tr)), tag,
+ `${PATH_FILES}?needed_tag=${encodeURIComponent(tag)}`);
});
{% if allow_edit %}
document.getElementById("sync_checkbox").checked = ! file_data.flags.includes("do not sync");
document.getElementById("added_tag").value = "";
const datalist = document.getElementById("unused_tags");
datalist.innerHTML = "";
- file_data.unused_tags.forEach((tag) => { new_child_to("option", datalist, tag); });
+ file_data.unused_tags.forEach((tag) => { add_child_to("option", datalist, {textContent: tag}); });
{% endif %}
td_present = document.getElementById("presence");
td_present.innerHTML = "";
if (file_data.present) {
- const a = new_child_to("a", td_present, "yes");
- a.href = "/{{page_names.download}}/{{file.yt_id}}";
- td_present.appendChild(document.createTextNode(" "));
- const button = new_child_to("button", td_present, "add as next");
- button.onclick = function() { player_command("inject_{{file.digest.b64}}"); }
+ add_a_to(td_present, "yes", "/{{page_names.download}}/{{file.yt_id}}");
+ add_text_to(td_present, " ");
+ add_player_btn_to(td_present, 'add as next', `inject_${file_data.digest}`);
} else {
td_present.textContent = "no";
}
var needed_tags = {{needed_tags|tojson|safe}};
function select_tag() {
- if (tags_select.selectedIndex < 1) {
- return;
- }
- const chosen_tag = document.getElementById('tags_select').value;
- needed_tags.push(chosen_tag);
- update_filter_inputs();
+ if (tags_select.selectedIndex < 1) {
+ return;
+ }
+ const chosen_tag = document.getElementById('tags_select').value;
+ needed_tags.push(chosen_tag);
+ update_filter_inputs();
}
function update_filter_inputs() {
- const tags_select = document.getElementById('tags_select');
- while (tags_select.options.length > 0) {
- tags_select.remove(0);
- }
- new_child_to('option', tags_select, 'add');
- all_tags.forEach((tag) => {
- if (needed_tags.includes(tag)) {
- return;
+ const tags_select = document.getElementById('tags_select');
+ while (tags_select.options.length > 0) {
+ tags_select.remove(0);
}
- const option = new_child_to('option', tags_select, tag);
- });
- const tags_div = document.getElementById("tags");
- tags_div.innerHTML = '';
- needed_tags.forEach((chosen_tag) => {
- const tag_text_node = document.createTextNode(` ${chosen_tag} `);
- tags_div.appendChild(tag_text_node);
- const btn_del = new_child_to('button', tags_div, 'x');
- btn_del.onclick = function() {
- tag_text_node.remove();
- btn_del.remove();
- needed_tags = needed_tags.filter(tag => tag !== chosen_tag);
- update_filter_inputs();
- };
- });
- update_files_list();
+ add_child_to('option', tags_select, {textContent: 'add'});
+ all_tags.forEach((tag) => {
+ if (needed_tags.includes(tag)) {
+ return;
+ }
+ add_child_to('option', tags_select, {textContent: tag});
+ });
+ const tags_div = document.getElementById("tags");
+ tags_div.innerHTML = '';
+ needed_tags.forEach((chosen_tag) => {
+ const tag_text_node = add_text_to(tags_div, ` ${chosen_tag} `);
+ add_child_to('button', tags_div, {
+ textContent: 'x',
+ onclick: function() {
+ tag_text_node.remove();
+ btn_del.remove();
+ needed_tags = needed_tags.filter(tag => tag !== chosen_tag);
+ update_filter_inputs();
+ }
+ });
+ });
+ update_files_list();
}
async function update_files_list() {
{{ macros.js_manage_sortable_table("rel_path") }}
var items_for_sortable_table = [];
function populate_list_item_row(tr, file) {
- new_child_to('td', tr, file.size);
- new_child_to('td', tr, file.duration);
- const td_inject = new_child_to('td', tr);
- const btn_inject = new_child_to('button', td_inject);
- btn_inject.onclick = function() { player_command(`inject_${file.digest}`) };
- btn_inject.disabled = !file.present;
- btn_inject.textContent = 'inject';
- father_tag_links(new_child_to('td', tr), file.tags_showable);
- const td_link = new_child_to('td', tr);
- const a = new_child_to('a', td_link, file.rel_path);
- a.href = `${PATH_PREFIX_FILE}${file.digest}`;
+ add_child_to('td', tr, {textContent: file.size});
+ add_child_to('td', tr, {textContent: file.duration});
+ const td_inject = add_child_to('td', tr);
+ add_player_btn_to(td_inject, 'add as next', `inject_${file.digest}`, !file.present)
+ add_tag_links_to(add_child_to('td', tr), file.tags_showable);
+ add_a_to(add_child_to('td', tr), file.rel_path, `${PATH_PREFIX_FILE}${file.digest}`);
}
window.addEventListener('load', update_filter_inputs);
{% endblock %}
while (old_rows[0]) { old_rows[0].remove(); }
for (let i = 0; i < data.playlist_files.length; i++) {
const file = data.playlist_files[i];
- const tr = new_child_to('tr', table);
+ const tr = add_child_to('tr', table);
tr.classList.add(CLS_PLAYLIST_ROW);
- const td_anchor = new_child_to('td', tr);
- td_anchor.id = `${i}`
- const a_row = new_child_to('a', td_anchor, '#');
- a_row.href = `#${i}`
- const td_entry_control = new_child_to('td', tr);
+ add_a_to(add_child_to('td', tr, {id: `${i}`}), '#', `#${i}`);
+ const td_entry_control = add_child_to('td', tr);
td_entry_control.classList.add('entry_control');
if (i == data.idx) {
td_entry_control.textContent = 'playing';
['^', 'up'],
['v', 'down'],
['x', 'rm']]) {
- const btn = new_child_to('button', td_entry_control, symbol);
- btn.onclick = function() { player_command(`${prefix}_${i}`) };
+ add_player_btn_to(td_entry_control, symbol, `${prefix}_${i}`);
}
}
- const td_link = new_child_to('td', tr);
- const a_file = new_child_to('a', td_link, file.rel_path);
- a_file.href = `${PATH_PREFIX_FILE}${file.digest}`;
+ add_a_to(add_child_to('td', tr), file.rel_path, `${PATH_PREFIX_FILE}${file.digest}`);
}
};
{% endblock %}
{{ macros.js_manage_sortable_table("name") }}
var items_for_sortable_table = {{tags|tojson|safe}};
function populate_list_item_row(tr, tag) {
- a_name = new_child_to('a', new_child_to('td', tr), tag.name);
- a_name.href = `${PATH_FILES}?needed_tag=${encodeURIComponent(tag.name)}`;
- new_child_to('td', tr, tag.number);
+ add_a_to(add_child_to('td', tr), tag.name,
+ `${PATH_FILES}?needed_tag=${encodeURIComponent(tag.name)}`);
+ add_child_to('td', tr, {textContent: tag.number});
}
window.addEventListener('load', draw_sortable_table);
{% endblock %}
const td = document.getElementById("status");
td.innerHTML = "";
if ("absent" == data.status) {
- a = new_child_to("a", td, "download?");
- a.href = "/{{page_names.download}}/{{video_data.id_}}";
+ add_a_to(td, "download?", "/{{page_names.download}}/{{video_data.id_}}");
} else if ("present" == data.status) {
- a = new_child_to("a", td, data.path);
- a.href = "/{{page_names.file}}/" + data.digest;
+ add_a_to(td, data.path, "/{{page_names.file}}/" + data.digest);
} else {
- td.appendChild(document.createTextNode(`${data.status}`));
+ add_text_to(td, `${data.status}`);
}
}
{% endblock %}