@oxymoron.13/tizentube-s95b 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +51 -42
  2. package/S95B-CHANGES.txt +12 -4
  3. package/UPSTREAM-README.md +42 -0
  4. package/dist/service.js +3 -0
  5. package/dist/userScript.js +2 -2
  6. package/mods/config.js +117 -0
  7. package/mods/domrect-polyfill.js +104 -0
  8. package/mods/features/adblock.js +584 -0
  9. package/mods/features/autoFrameRate.js +42 -0
  10. package/mods/features/enableFeatures.js +19 -0
  11. package/mods/features/moreSubtitles.js +378 -0
  12. package/mods/features/pictureInPicture.js +198 -0
  13. package/mods/features/preferredVideoQuality.js +101 -0
  14. package/mods/features/s95bCodec.js +45 -0
  15. package/mods/features/s95bI18n.js +28 -0
  16. package/mods/features/s95bMenu.js +137 -0
  17. package/mods/features/s95bOptions.js +30 -0
  18. package/mods/features/s95bPlayback.js +29 -0
  19. package/mods/features/sponsorblock.js +437 -0
  20. package/mods/features/standaloneUserscript.js +107 -0
  21. package/mods/features/updater.js +119 -0
  22. package/mods/features/userAgentSpoofing.js +73 -0
  23. package/mods/features/videoQueuing.js +64 -0
  24. package/mods/package-lock.json +2321 -0
  25. package/mods/package.json +33 -0
  26. package/mods/resolveCommand.js +381 -0
  27. package/mods/rollup.config.js +41 -0
  28. package/mods/spatial-navigation-polyfill.js +1756 -0
  29. package/mods/tiny-sha256.js +99 -0
  30. package/mods/translations/i18nResources.js +11 -0
  31. package/mods/translations/index.js +18 -0
  32. package/mods/translations/language-names.js +981 -0
  33. package/mods/translations/resources/ar.json +308 -0
  34. package/mods/translations/resources/az.json +308 -0
  35. package/mods/translations/resources/bs.json +308 -0
  36. package/mods/translations/resources/cs.json +308 -0
  37. package/mods/translations/resources/de.json +308 -0
  38. package/mods/translations/resources/dk.json +308 -0
  39. package/mods/translations/resources/el.json +308 -0
  40. package/mods/translations/resources/en.json +308 -0
  41. package/mods/translations/resources/es-419.json +308 -0
  42. package/mods/translations/resources/es.json +308 -0
  43. package/mods/translations/resources/fi-FI.json +308 -0
  44. package/mods/translations/resources/fr.json +311 -0
  45. package/mods/translations/resources/hr.json +308 -0
  46. package/mods/translations/resources/hu.json +308 -0
  47. package/mods/translations/resources/id.json +308 -0
  48. package/mods/translations/resources/it.json +308 -0
  49. package/mods/translations/resources/ja.json +308 -0
  50. package/mods/translations/resources/lt.json +308 -0
  51. package/mods/translations/resources/lv.json +308 -0
  52. package/mods/translations/resources/pl.json +308 -0
  53. package/mods/translations/resources/pt-BR.json +308 -0
  54. package/mods/translations/resources/pt-PT.json +308 -0
  55. package/mods/translations/resources/ro.json +310 -0
  56. package/mods/translations/resources/ru.json +308 -0
  57. package/mods/translations/resources/sr-Cyrl.json +308 -0
  58. package/mods/translations/resources/sr-Latn.json +308 -0
  59. package/mods/translations/resources/tlh.json +308 -0
  60. package/mods/translations/resources/tr.json +308 -0
  61. package/mods/translations/resources/uk.json +308 -0
  62. package/mods/translations/resources/vi.json +309 -0
  63. package/mods/translations/resources/zh-CN.json +308 -0
  64. package/mods/translations/resources/zh-TW.json +308 -0
  65. package/mods/translations/update-translations.js +55 -0
  66. package/mods/ui/chapters.js +137 -0
  67. package/mods/ui/clock.js +71 -0
  68. package/mods/ui/customCommandExecution.js +49 -0
  69. package/mods/ui/customGuideAction.js +119 -0
  70. package/mods/ui/customUI.js +192 -0
  71. package/mods/ui/customYTSettings.js +29 -0
  72. package/mods/ui/disableWhosWatching.js +48 -0
  73. package/mods/ui/settings.js +1024 -0
  74. package/mods/ui/sidebarModification.js +179 -0
  75. package/mods/ui/speedUI.js +119 -0
  76. package/mods/ui/theme.js +26 -0
  77. package/mods/ui/ui.css +157 -0
  78. package/mods/ui/ui.js +261 -0
  79. package/mods/ui/ytUI.js +510 -0
  80. package/mods/userScript.js +28 -0
  81. package/mods/utils/ASTParser.js +67 -0
  82. package/mods/utils/innerTubeCalls.js +138 -0
  83. package/package.json +11 -5
  84. package/service/package-lock.json +4193 -0
  85. package/service/package.json +29 -0
  86. package/service/rollup.config.js +47 -0
  87. package/service/service.js +121 -0
@@ -0,0 +1,179 @@
1
+ import { getGuide } from '../utils/innerTubeCalls.js';
2
+ import { configRead, configWrite } from '../config.js';
3
+ import { buttonItem, overlayPanelItemListRenderer, showModal } from './ytUI.js';
4
+ import { t } from 'i18next';
5
+
6
+ function showSetting(settingType, parameters) {
7
+ if (settingType === 'MOVE_GUIDE_BUTTON') {
8
+ const order = configRead('sidebarContentsOrder');
9
+
10
+ const browseId = parameters.item.guideEntryRenderer.navigationEndpoint?.browseEndpoint?.browseId
11
+ || (parameters.item.guideEntryRenderer.navigationEndpoint?.searchEndpoint && 'search');
12
+ const index = order.findIndex(item => {
13
+ if (typeof item === 'object' && item !== null) {
14
+ return item.browseId === browseId;
15
+ } else {
16
+ return item === browseId;
17
+ }
18
+ });
19
+
20
+ if (index === -1) {
21
+ return showSetting('', true);
22
+ }
23
+
24
+ if (parameters.direction === 'up' && index > 0) {
25
+ const temp = order[index - 1];
26
+ order[index - 1] = order[index];
27
+ order[index] = temp;
28
+ } else if (parameters.direction === 'down' && index < order.length - 1) {
29
+ const temp = order[index + 1];
30
+ order[index + 1] = order[index];
31
+ order[index] = temp;
32
+ }
33
+ configWrite('sidebarContentsOrder', order);
34
+
35
+ return showSetting('', true);
36
+ } else if (settingType === 'SHOW_GUIDE_BUTTONS') {
37
+ const title = parameters.item.guideEntryRenderer.formattedTitle.simpleText;
38
+
39
+ const buttons = [];
40
+ buttons.push(
41
+ buttonItem(
42
+ {
43
+ title: t('settings.options.uiSettings.options.sortSidebarContents.moveUp.title'),
44
+ subtitle: t('settings.options.uiSettings.options.sortSidebarContents.moveUp.subtitle')
45
+ },
46
+ {
47
+ icon: 'UP_ARROW'
48
+ },
49
+ [
50
+ {
51
+ customAction: {
52
+ action: 'MOVE_GUIDE_BUTTON',
53
+ parameters: {
54
+ settingType,
55
+ direction: 'up',
56
+ item: parameters.item
57
+ }
58
+ }
59
+ },
60
+ {
61
+ signalAction: {
62
+ signal: 'POPUP_BACK'
63
+ }
64
+ }
65
+ ]
66
+ )
67
+ )
68
+
69
+ buttons.push(
70
+ buttonItem(
71
+ {
72
+ title: t('settings.options.uiSettings.options.sortSidebarContents.moveDown.title'),
73
+ subtitle: t('settings.options.uiSettings.options.sortSidebarContents.moveDown.subtitle')
74
+ },
75
+ {
76
+ icon: 'DOWN_ARROW'
77
+ },
78
+ [
79
+ {
80
+ customAction: {
81
+ action: 'MOVE_GUIDE_BUTTON',
82
+ parameters: {
83
+ settingType,
84
+ direction: 'down',
85
+ item: parameters.item
86
+ }
87
+ }
88
+ },
89
+ {
90
+ signalAction: {
91
+ signal: 'POPUP_BACK'
92
+ }
93
+ }
94
+ ]
95
+ )
96
+ )
97
+
98
+ return showModal(
99
+ title,
100
+ overlayPanelItemListRenderer(buttons),
101
+ 'tt-move-guide-button-modal'
102
+ );
103
+ }
104
+ getGuide().then(guide => {
105
+ const buttons = [];
106
+
107
+ let idx = 0;
108
+ const guideItems = guide.items[0].guideSectionRenderer.originalItems
109
+ || guide.items[0].guideSectionRenderer.items;
110
+ for (const item of guideItems) {
111
+ const title = item.guideEntryRenderer.formattedTitle.simpleText;
112
+ const icon = item.guideEntryRenderer.icon?.iconType;
113
+ const browseId = item.guideEntryRenderer.navigationEndpoint?.browseEndpoint ? item.guideEntryRenderer.navigationEndpoint.browseEndpoint.browseId : 'search';
114
+
115
+ buttons.push(
116
+ buttonItem(
117
+ {
118
+ title,
119
+ },
120
+ {
121
+ icon,
122
+ secondaryIcon: settingType === 'disabledSidebarContents' ?
123
+ configRead(settingType)?.includes(browseId) ?
124
+ 'CHECK_BOX' : 'CHECK_BOX_OUTLINE_BLANK'
125
+ : null
126
+ },
127
+ [
128
+ settingType === 'disabledSidebarContents' ?
129
+ {
130
+ setClientSettingEndpoint: {
131
+ settingDatas: [
132
+ {
133
+ clientSettingEnum: {
134
+ item: 'disabledSidebarContents'
135
+ },
136
+ arrayValue: browseId
137
+ }
138
+ ]
139
+ }
140
+ } :
141
+ {
142
+ customAction: {
143
+ action: 'SHOW_GUIDE_BUTTONS',
144
+ parameters: {
145
+ settingType,
146
+ idx,
147
+ item
148
+ }
149
+ }
150
+ },
151
+ ...(settingType === 'disabledSidebarContents' ? [{
152
+ customAction: {
153
+ action: 'RELOAD_GUIDE_OPTIONS',
154
+ parameters: {
155
+ settingType,
156
+ idx,
157
+ item
158
+ }
159
+ }
160
+ }] : [])
161
+ ]
162
+ )
163
+ );
164
+ idx++;
165
+ }
166
+
167
+ showModal(
168
+ {
169
+ title: settingType === 'disabledSidebarContents' ? t('settings.options.uiSettings.options.disableSidebarContents.title') : t('settings.options.uiSettings.options.sortSidebarContents.title'),
170
+ subtitle: settingType === 'disabledSidebarContents' ? t('settings.options.uiSettings.options.disableSidebarContents.subtitle') : t('settings.options.uiSettings.options.sortSidebarContents.subtitle')
171
+ },
172
+ overlayPanelItemListRenderer(buttons),
173
+ 'tt-sidebar-settings',
174
+ parameters === true
175
+ );
176
+ });
177
+ }
178
+
179
+ export default showSetting;
@@ -0,0 +1,119 @@
1
+ import { configRead } from '../config.js';
2
+ import { showModal, buttonItem, overlayPanelItemListRenderer } from './ytUI.js';
3
+ import { t } from 'i18next';
4
+
5
+ const interval = setInterval(() => {
6
+ const videoElement = document.querySelector('video');
7
+ if (videoElement) {
8
+ execute_once_dom_loaded_speed();
9
+ clearInterval(interval);
10
+ }
11
+ }, 1000);
12
+
13
+ function execute_once_dom_loaded_speed() {
14
+ document.querySelector('video').addEventListener('canplay', () => {
15
+ document.getElementsByTagName('video')[0].playbackRate = configRead('videoSpeed');;
16
+ });
17
+
18
+ const eventHandler = (evt) => {
19
+ if (evt.keyCode == 406 || evt.keyCode == 191) {
20
+ evt.preventDefault();
21
+ evt.stopPropagation();
22
+ if (evt.type === 'keydown') {
23
+ speedSettings();
24
+ return false;
25
+ }
26
+ return true;
27
+ };
28
+ }
29
+
30
+ // Red, Green, Yellow, Blue
31
+ // 403, 404, 405, 406
32
+ // ---, 172, 170, 191
33
+ document.addEventListener('keydown', eventHandler, true);
34
+ document.addEventListener('keypress', eventHandler, true);
35
+ document.addEventListener('keyup', eventHandler, true);
36
+ }
37
+
38
+ function speedSettings() {
39
+ const currentSpeed = configRead('videoSpeed');
40
+ let selectedIndex = 0;
41
+ const maxSpeed = 5;
42
+ const increment = configRead('speedSettingsIncrement') || 0.25;
43
+ const buttons = [];
44
+ for (let speed = increment; speed <= maxSpeed; speed += increment) {
45
+ const fixedSpeed = Math.round(speed * 100) / 100;
46
+ buttons.push(
47
+ buttonItem(
48
+ { title: `${fixedSpeed}x` },
49
+ null,
50
+ [
51
+ {
52
+ signalAction: {
53
+ signal: 'POPUP_BACK'
54
+ }
55
+ },
56
+ {
57
+ setClientSettingEndpoint: {
58
+ settingDatas: [
59
+ {
60
+ clientSettingEnum: {
61
+ item: 'videoSpeed'
62
+ },
63
+ intValue: fixedSpeed.toString()
64
+ }
65
+ ]
66
+ }
67
+ },
68
+ {
69
+ customAction: {
70
+ action: 'SET_PLAYER_SPEED',
71
+ parameters: fixedSpeed.toString()
72
+ }
73
+ }
74
+ ]
75
+ )
76
+ );
77
+ if (currentSpeed === fixedSpeed) {
78
+ selectedIndex = buttons.length - 1;
79
+ }
80
+ }
81
+
82
+ buttons.push(
83
+ buttonItem(
84
+ { title: t('player.playbackSpeed.fixStuttering') },
85
+ null,
86
+ [
87
+ {
88
+ signalAction: {
89
+ signal: 'POPUP_BACK'
90
+ }
91
+ },
92
+ {
93
+ setClientSettingEndpoint: {
94
+ settingDatas: [
95
+ {
96
+ clientSettingEnum: {
97
+ item: 'videoSpeed'
98
+ },
99
+ intValue: '1.0001'
100
+ }
101
+ ]
102
+ }
103
+ },
104
+ {
105
+ customAction: {
106
+ action: 'SET_PLAYER_SPEED',
107
+ parameters: '1.0001'
108
+ }
109
+ }
110
+ ]
111
+ )
112
+ );
113
+
114
+ showModal(t('player.playbackSpeed.title'), overlayPanelItemListRenderer(buttons, selectedIndex), 'tt-speed');
115
+ }
116
+
117
+ export {
118
+ speedSettings
119
+ }
@@ -0,0 +1,26 @@
1
+ import { configRead } from '../config.js';
2
+
3
+ const style = document.createElement('style');
4
+ let css = '';
5
+
6
+ function updateStyle() {
7
+ css = `
8
+ ytlr-guide-response yt-focus-container {
9
+ background-color: ${configRead('focusContainerColor')};
10
+ }
11
+
12
+ #container {
13
+ background-color: ${configRead('routeColor')} !important;
14
+ }
15
+ `;
16
+ const existingStyle = document.querySelector('style[nonce]');
17
+ if (existingStyle) {
18
+ existingStyle.textContent += css;
19
+ } else {
20
+ style.textContent = css;
21
+ }
22
+ };
23
+
24
+ document.head.appendChild(style);
25
+ updateStyle();
26
+ export default updateStyle;
package/mods/ui/ui.css ADDED
@@ -0,0 +1,157 @@
1
+ .ytaf-ui-container {
2
+ position: absolute;
3
+ top: 10%;
4
+ left: 10%;
5
+ right: 10%;
6
+ bottom: 10%;
7
+
8
+ background: rgba(0, 0, 0, 0.8);
9
+ color: white;
10
+ border-radius: 20px;
11
+ padding: 20px;
12
+ font-size: 1.5rem;
13
+ z-index: 1000;
14
+ }
15
+
16
+ .ytaf-ui-container :focus {
17
+ outline: 4px red solid;
18
+ }
19
+
20
+ .ytaf-ui-container h1 {
21
+ margin: 0;
22
+ margin-bottom: 0.5em;
23
+ text-align: center;
24
+ }
25
+
26
+ .ytaf-ui-container input[type='checkbox'] {
27
+ width: 1.4rem;
28
+ height: 1.4rem;
29
+ }
30
+
31
+ .ytaf-ui-container input[type='radio'] {
32
+ width: 1.4rem;
33
+ height: 1.4rem;
34
+ }
35
+
36
+ .ytaf-ui-container label {
37
+ display: block;
38
+ font-size: 1.4rem;
39
+ }
40
+
41
+ .ytaf-notification-container {
42
+ position: absolute;
43
+ right: 10px;
44
+ bottom: 10px;
45
+ font-size: 16pt;
46
+ z-index: 1200;
47
+ }
48
+
49
+ .ytaf-notification-container .message {
50
+ background: rgba(0, 0, 0, 0.7);
51
+ color: white;
52
+ padding: 1em;
53
+ margin: 0.5em;
54
+ transition: all 0.3s ease-in-out;
55
+ opacity: 1;
56
+ line-height: 1;
57
+ border-right: 10px solid rgba(50, 255, 50, 0.3);
58
+ display: inline-block;
59
+ float: right;
60
+ }
61
+
62
+ .ytaf-notification-container .message-hidden {
63
+ opacity: 0;
64
+ margin: 0 0.5em;
65
+ padding: 0 1em;
66
+ line-height: 0;
67
+ }
68
+
69
+ /* Fixes transparency effect for the video player */
70
+
71
+ .ytLrWatchDefaultShadow,
72
+ div[idomkey="shadow"] {
73
+ background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0.8) 90%) !important;
74
+ background-color: rgba(0, 0, 0, 0.3) !important;
75
+ display: block !important;
76
+ height: 100% !important;
77
+ pointer-events: none !important;
78
+ position: absolute !important;
79
+ width: 100% !important;
80
+ }
81
+
82
+ /* https://github.com/webosbrew/youtube-webos/commit/4fbe38a18df31ddd62b6cf15f141dd58e1d1a71d */
83
+ .ytLrWatchDefault2025Shadow {
84
+ background-color: rgba(11, 11, 11, 0.5) !important;
85
+ }
86
+
87
+ /* Fixes shorts having a black background */
88
+
89
+ .ytLrTileHeaderRendererShorts {
90
+ background-image: none !important;
91
+ }
92
+
93
+ /* Multiline support for strings in the UI */
94
+
95
+ .ytLrOverlayPanelHeaderRendererSubtitle {
96
+ white-space: pre-wrap !important;
97
+ }
98
+
99
+ /* Fixes SponsorBlock segments overlapping with the playhead */
100
+
101
+ .ytLrProgressBarPlayhead {
102
+ z-index: 1 !important;
103
+ }
104
+
105
+ .ytLrProgressBarPlayed {
106
+ z-index: 1 !important;
107
+ }
108
+
109
+ .ytLrSearchBarSearchVoice {
110
+ display: block;
111
+ position: absolute;
112
+ left: 0;
113
+ top: 0;
114
+ pointer-events: auto
115
+ }
116
+
117
+ .ytLrSearchVoiceHost {
118
+ font-size: 3rem;
119
+ }
120
+
121
+ .ytLrSearchVoiceMicButtonHost {
122
+ color: rgba(255, 255, 255, 0.7);
123
+ }
124
+
125
+ .ytLrSearchVoiceMicButtonHost {
126
+ background-color: rgba(255, 255, 255, 0.1);
127
+ border-radius: 50%;
128
+ color: #f1f1f1;
129
+ display: block;
130
+ text-align: center;
131
+ width: 1em;
132
+ height: 1em;
133
+ }
134
+
135
+ .ytLrSearchVoiceMicButtonIcon {
136
+ display: inline-block;
137
+ font-size: .5em;
138
+ height: .5em;
139
+ width: .5em;
140
+ height: 1em;
141
+ width: 1em;
142
+ margin-top: .5em;
143
+ vertical-align: top !important;
144
+ }
145
+
146
+ .ytContribIconHost {
147
+ display: inline-block;
148
+ vertical-align: middle;
149
+ }
150
+
151
+ .ytContribIconTvArrowLeft::before {
152
+ content: "\e822";
153
+ }
154
+
155
+ .ytContribIconHost::before {
156
+ font-family: "YouTube Icons Outlined";
157
+ }