Open muescha opened 3 months ago
Hi @muescha
the current implementation involves choosing from a given list of templates. But there is an alternative option. Which was not included for reasons of obviousness to users. In it the user can enter the selected format himself
You can try uncommenting. If this option suits you, then I will leave it. I assumed that the user is stupid and will not be able to figure it out. It’s easier and safer to choose from a ready-list. Because there are no visual hints for the user. And as you previously issue, there are quite big problems with the Wiki. And it was difficult for me to convey the possibilities clearly and clearly to the user. And laziness of course.
If you have any problems or questions, write here or by email, I will try to answer and help you.
yes - the first strategy with user edited templates are a lot more complicated.
the dropdown is not working in my case - I don't invested too much time to investigage. but a short hint I found in the console:
GET https://raingart.github.io/nova/js/options.js net::ERR_ABORTED 404 (Not Found)
I opened a new issue: #185
I would also do a more template aproach - put each value in braches {}
- but also with this the template is not easy to read:
{left}/{left*speed} ({done%}) {speed}x
I think the current state is better to understand by an user.
so leaving the question 1-3:
it is up to you what would be the best implementation.
I generated the userscript right from the github repo (created a script: #186) what is different to the dev ver?
with the video I got it: it shows nothing because the dropdown was filtered by the exisiting template, because of no match there was no value.
I would redesign the template filed in the form of:
Use Templates
: there is a dropdown with some predefined templates which replaces the template string (this is your strategy 2)Insert field
: there is a dropdown of all available fields (the dropdown should not filtered) which are inserted at the cursor:Label | Value | Example |
---|---|---|
speed | {speed} | 1.5 |
left | {left} | 00:02:30 |
left% | {left%} | 25% |
left*speed | {left*speed} | 00:01:40 |
done | {done} | 00:07:30 |
done% | {done%} | 75% |
duration | {duration} | 00:10:00 |
duration*speed | {duration*speed} | 00:06:40 |
thx for the time-remaining.txt
- is the current state in any branch?
what is different to the dev ver?
the structure itself remains the same, just a little refactoring and fixing. Since I wrote it myself, git push
occurred when cumulative changes denoting a new release.
branch now updated
Changelog.md:
Apply if URL has link to comment
option for [video-autopause]Apply if URL has link to comment
option for [video-autostop]Custom colors
option for [sponsor-block]Get screenshot size from
option for [player-quick-buttons]clipboard
and formats
in Screenshot out [player-quick-buttons]popup
in Screenshot out [player-quick-buttons]Min iframe width
option for [embed-popup]speed
option for [time-remaining] by @mueschaShow full title
in new plugin for [thumbs-title-show-full]new plugin
removed plugin:
fixes in plugins:
optimized plugins:
minor optimized plugins:
I don't know git very well
That's why I added you to Collaborators
I think it will be easier for you this way than when I guess to move this commit to a new branch
git cherry-pick
and even more so solve “branch has conflicts”!
change any files and documentation as you see fit
I simplifying the format a little.
datalist
is not suitable for displaying data from 3 columns. It is more adapted for 2nd.
I also made a few examples at the beginning (I think they are the most popular, maybe) and then a list of all available commands
That looks great :)
I tried also a switch function - and found some problems in options.js
- i tried to use 'data-dependent': { 'time_remaining_format_use_custom': false },
but this was only possible without the changes in options.js
see https://github.com/muescha/Nova-YouTube-extension/commit/542aa105f51df458e8b1f968824dd748298bdc13
checkbox value & string value
// return [subtargetEl.value];
return [(subtargetEl.type == 'checkbox') ? subtargetEl.checked.toString() : subtargetEl.value];
I changed it to the previous comment, because the checkbox always have the value `on` regardless if is checked or unchecked. I added a `.toString()` because the comparison in line 101 and 103 also do a `.toString()` for each rule value.
removing the check for subtargetEl.checked
In the line 100 this check skipped all rule tests if a checkbox is checked and if there is a data-dependent
with a false
value: it did not do the check.
Note: I am not aware of other side effects with this change.
(subtargetEl.checked && !subtargetEl.matches('[type="radio"]'))
Draft:
I tried with radio boxes but they are not that nice because I can not write in one line:
- time pattern: (x) custom ( ) templates
time_remaining_format_use_custom_radio_1: {
_tagName: 'input',
label: 'Use custom template',
type: 'radio',
name: `time_remaining_format_use_custom_radio`,
checked: true,
value: `true`,
},
time_remaining_format_use_custom_radio_2: {
_tagName: 'input',
label: 'Use pattern templates',
type: 'radio',
name: `time_remaining_format_use_custom_radio`,
value: `false`,
},
note: I don't found code snippets about radio so I added some info to the wiki (https://github.com/raingart/Nova-YouTube-extension/wiki/plugin#radio)
attrDependencies
(code) had only one function: hide all options when the plugin is deactivated.!
sign at the beginning codemy short-sightedness led to the fact that instead of some universal method there was a modification of the attrDependencies
that was initially not designed for this module.
select
tag you need to specify an arraycheckbox
you need to specify Boolean parameters due to conversion when saving (I don’t remember why I did this) code. At the same time, the inversion of checkbox (!
) For Boolean type became naturally unavailableselect
tag does not convert codethat is, such use cases are available
'data-dependent': { 'parent_checkbox_name': Boolean }
,'data-dependent': { 'parent_select_name': ['String', 'String-Number'], '!String' }
,'data-dependent': { 'parent_input_name': "0" },
and 'data-dependent': { 'parent_input_name': "!0" },
it is also possible to "overlap" options. Because they are processed sequentially. You can make a mistake where two or more options may not work correctly.
Here is the entire list of data formats that I know and use that are saved:
The very idea of implementing a more flexible module terrifies me. I don't have the slightest idea how to implement it. I compared it to the current implementation, which is very limited, but it already exists and somehow works.
for testing you can select the speed plugin covers almost all use cases
At the very beginning I tried to look for a ready-made solution, but I couldn’t find it. Perhaps if you put the instructions for LLM (GPT like) correctly, it will be able to generate a ready-made function. But I can't even describe the task. Since, as you previously indicated, the data storage system is not optimal and uses different data storage formats for similar types.
For example, why are nets stored in String? The answer is simply because then the inversion (!
) stops working. That is, one crippling implementation will ruin the subsequent ones
So I found a wonderful error that confirms the fragility and non-obviousness of the current implementation
doesn't work completely. I probably added just the inverse of the empty string in desperation https://github.com/raingart/Nova-YouTube-extension/blob/2437cb554a91c436ab3ad7bf91bd03729b5e5099/plugins/player/speed.js#L977
since the specified type is Boolean and not String https://github.com/raingart/Nova-YouTube-extension/blob/2437cb554a91c436ab3ad7bf91bd03729b5e5099/plugins/player/speed.js#L744
need fix { label: 'none', value: 'false' },
in speed.js#L744
despite the fact that when saved from convects into a Boolean
("NovaTube") "sync" : "undefined" => "{"rate_hotkey":false}"
Yes, the code is a bit fragile.
Initially, I attempted to use 'data-dependent': { 'time_remaining_format_use_custom': false }
.
During debugging, I discovered that setting this value to true
always works. However, this is not due to the check in || ruleValues.some(i => currentValuesList.includes(i.toString()))
, but rather because of the shortcut subtargetEl.checked
.
I also found that regardless of the checkbox state, the value is always on
; there is no off
value, nor is there an empty value. Even when unchecked, the value remains on
.
To address this, I made the following change:
- return [subtargetEl.value];
+ return [(subtargetEl.type == 'checkbox') ? subtargetEl.checked.toString() : subtargetEl.value];
I added toString()
to ensure all values are treated as strings.
With this change, there's no need to change the boolean values at 'data-dependent' to string, since all values are now strings (thanks to subtargetEl.checked.toString()
and currentValuesList.includes(i.toString())
).
Additionally, I removed this check:
- (subtargetEl.checked && !subtargetEl.matches('[type="radio"]')) // skip radio (which is always checked. Unlike a checkbox)
+ false //(subtargetEl.checked && !subtargetEl.matches('[type="radio"]')) // skip radio (which is always checked. Unlike a checkbox)
The reason for this removal is that, otherwise, the code never reaches the negation check. I tested using !on
and !true
, but this line prevented the negation check when the checkbox was checked. I didn't account for any side effects with this change, so it may need to be reviewed and fine-tuned further.
BTW:
I played a little with the radio and added a fieldset:
this can be done if we have a _tagname: 'fieldset'
element where the legend: 'abc'
creates a legend
html element, and we allow a field with children
where all the child values goes into.
the style for the radio buttons would change to show the ( )
in front of the text.
here is the resulting html snippet for the screenshot:
<!--
ul ul ul {
list-style-type: none;
}
li>label:before {
content: "↪";
margin: 0 .5em;
color: #343a45;
}
-->
<li class="item">
<div class="info" tooltip="Remaining time until the end of the video" flow="up">
<label for="time-remaining">Remaining time</label>
<a href="https://github.com/raingart/Nova-YouTube-extension/wiki/plugins#time-remaining" target="_blank"
title="More info">?</a>
</div>
<div class="opt">
<input type="checkbox" name="time-remaining" id="time-remaining">
</div>
<ul data-dependent="{"time-remaining":[true]}">
<li><!--<label for="time_remaining_format_use_custom_radio_fieldset">select a template</label>-->
<fieldset legend="selects a template" name="time_remaining_format_use_custom_radio_fieldset"
id="time_remaining_format_use_custom_radio_fieldset" class="collapse">
<legend>Select pattern template</legend>
<ul>
<li class=""><input type="radio" name="time_remaining_format_use_custom_radio" checked="true"
value="true" id="time_remaining_format_use_custom_radio_1" class=""><label
for="time_remaining_format_use_custom_radio_1" class="collapse">Custom</label></li>
<li style=""><input type="radio" name="time_remaining_format_use_custom_radio" value="false"
id="time_remaining_format_use_custom_radio_2" class=""><label
for="time_remaining_format_use_custom_radio_2" class="collapse">Templates</label></li>
</ul>
</fieldset>
</li>
<li style="
display:none"><label for="time_remaining_format_use_custom_radio_1" style="
">Use custom template</label><input type="radio" name="time_remaining_format_use_custom_radio" checked="true"
value="true" id="time_remaining_format_use_custom_radio_1" class=""></li>
<li style="
display:none"><label for="time_remaining_format_use_custom_radio_2">Use pattern templates</label><input type="radio"
name="time_remaining_format_use_custom_radio"
value="false"
id="time_remaining_format_use_custom_radio_2"
class="collapse">
</li>
<li data-dependent="{"time_remaining_format_use_custom_radio":true}"
tooltip="[^] - correction current playback speed" class=""><label for="time_remaining_format">Custom time
pattern</label><input type="text" list="time_remaining_format_help_list"
placeholder="{done%}/{duration^} ({rate})" minlength="4" maxlength="100"
required="true" name="time_remaining_format" id="time_remaining_format"
class="collapse"></li>
<li>
<datalist name="time_remaining_format_help_list" id="time_remaining_format_help_list">
<option value="{done}/{duration} ({done%})">0:10/0:44 (23%)</option>
<option value="{done^}/{duration^} {rate}">0:05/0:25 1.75x</option>
<option value="{left}/{duration} • {left%}">-0:34/0:44 • -77%</option>
<option value="{left^}/{duration^} {rate}">-0:19/0:25 1.75x</option>
<option value="{left}/{duration} • {left^}/{duration^} ({done%}) {rate}">-2:24/18:00 • -0:48/6:00 (87%)
3x
</option>
<option value="{left} {left^} {left%} • {done} {done^} {done%} • {duration} {duration^} • {rate}">-2:24
-0:48 -13% • 15:36 5:12 87% • 18:00 6:00 • 3x
</option>
<option value=" ">For a custom template, you can use these fields:</option>
<option value="{rate}">1.75x</option>
<option value="{left}">-0:34</option>
<option value="{left^}">-0:19</option>
<option value="{left%}">-77%</option>
<option value="{done}">0:10</option>
<option value="{done^}">0:05</option>
<option value="{done%}">23%</option>
<option value="{duration}">0:44</option>
<option value="{duration^}">0:25</option>
</datalist>
</li>
<li data-dependent="{"time_remaining_format_use_custom_radio":false}"
tooltip="[^] - correction current playback speed" class="hide"><label for="time_remaining_format_templates">Time
pattern templates</label><select required="true" name="time_remaining_format_templates"
id="time_remaining_format_templates" disabled="">
<option value="{left^}">{left^}</option>
<option value="{left^} ({done%})">{left^} ({done%})</option>
<option value="{left^} ({left%})">{left^} ({left%})</option>
<option value="{left}/{left^} ({done%})">{left}/{left^} ({done%})</option>
<option value="{left}">{left}</option>
<option value="{left%}">{left%}</option>
<option value="{done%}">{done%}</option>
<option value="{done^}/{left^}">{done^}/{left^}</option>
<option value="{done^}/{duration^}">{done^}/{duration^}</option>
<option value="{left^}/{duration^}">{left^}/{duration^}</option>
<option value="{left^}/{duration^} ({done%})">{left^}/{duration^} ({done%})</option>
<option value="{left}/{left^} ({done%}) {rate}">{left}/{left^} {rate}</option>
</select></li>
<li><label for="time_remaining_position">Render section</label><select name="time_remaining_position"
id="time_remaining_position">
<option value="player">player</option>
<option value="description">description</option>
</select></li>
</ul>
</li>
I tried to implement radio
elements at the initial stages
but I came to the conclusion that they are generally useless. This is a restriction analogue to select
it takes up more space and has no functional advantage
for example in Remaining time > Render section or other places. select is easier to expand if necessary
only advantage is that all options are better visible for the user. and yes - every select can be shown as radio or as select.
If you don't like the radio thing, then I don't invest time to implement it :)
What:
playbackRate
to the time remaining calculation.Questions: 1) Should this be implemented in the current plugin, or should it be a separate plugin independent of the
time-remaining
plugin? A separate plugin would be code duplication, but might more clear in the options dialog. 2) Should it be added as an additional option totime-remaing
, similar to "time_remaining_position," with a setting likeshow_playbackRate: yes/no
? However, this would limit the customization of its position in the template string. 3) ShouldplaybackRate
be included in all format templates where speed is relevant?