nuvio-tizen 1.8.9 → 1.8.12

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.
package/config.xml CHANGED
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets"
3
- id="http://nuvio.tizen/NuvioTizen" version="1.0.0" viewmodes="maximized">
3
+ id="http://nuvio.tizen/NuvioTizen" version="1.8.12" viewmodes="maximized">
4
4
  <tizen:application id="Nuvio00001.Nuvio" package="Nuvio00001" required_version="2.4"/>
5
5
  <content src="index.html"/>
6
6
  <feature name="http://tizen.org/feature/screen.size.all"/>
package/css/style.css CHANGED
@@ -191,6 +191,14 @@ html, body {
191
191
  .modal-msg { font-size: 30px; line-height: 1.4; color: #e6e9ef; margin-bottom: 36px; }
192
192
  .modal-row { display: flex; justify-content: center; }
193
193
  .modal-btn { min-width: 200px; text-align: center; }
194
+ /* list picker (single choice) */
195
+ .pick-box { width: 720px; text-align: left; }
196
+ .pick-box .modal-msg { text-align: left; margin-bottom: 20px; }
197
+ .pick-list { max-height: 620px; overflow: hidden; }
198
+ .pick-item { padding: 14px 20px; margin-bottom: 8px; border-radius: 8px; background: #0e1117; border: 4px solid transparent; font-size: 24px; }
199
+ .pick-item.sel { background: #2a3346; }
200
+ .pick-item.focusable.focused { background: #818cf8; color: #0e1117; border-color: #fff; }
201
+
194
202
  .pill.danger { background: #3a2130; }
195
203
  .pill.danger.focusable.focused { background: #ef4444; color: #fff; }
196
204
  .reset-item .a-name { color: #f0a5a5; }
package/index.html CHANGED
@@ -4,7 +4,7 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=1920, height=1080, user-scalable=no">
6
6
  <title>Nuvio</title>
7
- <link rel="stylesheet" href="css/style.css?v=1.8.9">
7
+ <link rel="stylesheet" href="css/style.css?v=1.8.12">
8
8
  </head>
9
9
  <body>
10
10
  <!-- CSS-applied sentinel (kept off-screen); app.js waits for its width before rendering -->
@@ -47,13 +47,13 @@
47
47
 
48
48
  <!-- Load order matters: polyfills -> util -> data -> input -> player -> views -> app -->
49
49
  <!-- ?v= busts the TV webview cache on every release (keep in sync with package.json) -->
50
- <script src="js/polyfills.js?v=1.8.9"></script>
51
- <script src="js/util.js?v=1.8.9"></script>
52
- <script src="js/stremio.js?v=1.8.9"></script>
53
- <script src="js/keys.js?v=1.8.9"></script>
54
- <script src="js/focus.js?v=1.8.9"></script>
55
- <script src="js/player.js?v=1.8.9"></script>
56
- <script src="js/views.js?v=1.8.9"></script>
57
- <script src="js/app.js?v=1.8.9"></script>
50
+ <script src="js/polyfills.js?v=1.8.12"></script>
51
+ <script src="js/util.js?v=1.8.12"></script>
52
+ <script src="js/stremio.js?v=1.8.12"></script>
53
+ <script src="js/keys.js?v=1.8.12"></script>
54
+ <script src="js/focus.js?v=1.8.12"></script>
55
+ <script src="js/player.js?v=1.8.12"></script>
56
+ <script src="js/views.js?v=1.8.12"></script>
57
+ <script src="js/app.js?v=1.8.12"></script>
58
58
  </body>
59
59
  </html>
package/js/focus.js CHANGED
@@ -85,18 +85,37 @@ var Focus = (function () {
85
85
  }
86
86
  if (!cands.length) { return; }
87
87
 
88
- // Two-phase: land in the NEAREST row/column first (so vertical moves never
89
- // skip a row just because a farther element is better horizontally aligned),
90
- // then pick the closest within that band.
91
- var minP = Infinity;
92
- for (var j = 0; j < cands.length; j++) { if (cands[j].primary < minP) { minP = cands[j].primary; } }
93
- var BAND = 120;
94
- var best = null, bestCross = Infinity, bestP = Infinity;
95
- for (var k = 0; k < cands.length; k++) {
96
- var c = cands[k];
97
- if (c.primary > minP + BAND) { continue; }
98
- if (c.cross < bestCross || (c.cross === bestCross && c.primary < bestP)) {
99
- best = c.node; bestCross = c.cross; bestP = c.primary;
88
+ // Two-phase, direction-aware:
89
+ // - Vertical (UP/DOWN): first restrict to the NEAREST row (min primary =
90
+ // vertical distance), then pick the horizontally closest (min cross).
91
+ // - Horizontal (LEFT/RIGHT): first restrict to the SAME row (min cross =
92
+ // vertical offset), then pick the horizontally closest (min primary).
93
+ // This stops vertical moves skipping a short row, and stops horizontal moves
94
+ // jumping into another row (e.g. Settings -> LEFT should land on Search).
95
+ var vertical = (dir === 'UP' || dir === 'DOWN');
96
+ var best = null, bestSel = Infinity, bestTie = Infinity;
97
+
98
+ if (vertical) {
99
+ // nearest row first (min primary band), then closest horizontally
100
+ var BAND = 120, minP = Infinity;
101
+ for (var j = 0; j < cands.length; j++) { if (cands[j].primary < minP) { minP = cands[j].primary; } }
102
+ for (var k = 0; k < cands.length; k++) {
103
+ var c = cands[k];
104
+ if (c.primary > minP + BAND) { continue; }
105
+ if (c.cross < bestSel || (c.cross === bestSel && c.primary < bestTie)) {
106
+ best = c.node; bestSel = c.cross; bestTie = c.primary;
107
+ }
108
+ }
109
+ } else {
110
+ // same row only (absolute vertical tolerance), then nearest horizontally.
111
+ // No jump to another row/header at a row end — just don't move.
112
+ var ROW_TOL = 140;
113
+ for (var m = 0; m < cands.length; m++) {
114
+ var d = cands[m];
115
+ if (d.cross > ROW_TOL) { continue; }
116
+ if (d.primary < bestSel || (d.primary === bestSel && d.cross < bestTie)) {
117
+ best = d.node; bestSel = d.primary; bestTie = d.cross;
118
+ }
100
119
  }
101
120
  }
102
121
  if (best) { setFocus(best); }
package/js/views.js CHANGED
@@ -42,6 +42,31 @@ var Views = (function () {
42
42
  _modalScope = null; _modalPrevFocus = null;
43
43
  }
44
44
 
45
+ // A scrollable single-choice list overlay (D-pad). options = [[value,label],...]
46
+ function pickList(title, options, current, onPick) {
47
+ var existing = document.querySelector('.modal-overlay');
48
+ if (existing) { existing.parentNode.removeChild(existing); }
49
+ var overlay = U.el('div', 'modal-overlay');
50
+ var box = U.el('div', 'modal-box pick-box');
51
+ box.appendChild(U.el('div', 'modal-msg', title));
52
+ var listEl = U.el('div', 'pick-list');
53
+ var pref = null;
54
+ options.forEach(function (opt) {
55
+ var it = U.el('div', 'pick-item focusable' + (opt[0] === current ? ' sel' : ''), opt[1]);
56
+ it.__onselect = function () { closeModal(); onPick(opt[0]); };
57
+ if (opt[0] === current) { pref = it; }
58
+ listEl.appendChild(it);
59
+ });
60
+ box.appendChild(listEl);
61
+ overlay.appendChild(box);
62
+ document.body.appendChild(overlay);
63
+
64
+ _modalPrevFocus = Focus.current();
65
+ _modalScope = _current();
66
+ _modalOpen = true;
67
+ Focus.setScope(overlay, pref);
68
+ }
69
+
45
70
  function _current() {
46
71
  var names = ['home', 'detail', 'search', 'settings', 'addaddon'];
47
72
  for (var i = 0; i < names.length; i++) {
@@ -630,9 +655,11 @@ var Views = (function () {
630
655
  var cancelBtn = U.el('div', 'pill focusable', 'Cancel');
631
656
  confirmBtn.__onselect = doConfirm;
632
657
  cancelBtn.__onselect = function () { App.back(); };
633
- row.appendChild(confirmBtn);
658
+
659
+ // Order: Validate · Confirm · Cancel
660
+ var valBtn = null;
634
661
  if (cfg.validator) {
635
- var valBtn = U.el('div', 'pill focusable', 'Validate');
662
+ valBtn = U.el('div', 'pill focusable', 'Validate');
636
663
  valBtn.__onselect = function () {
637
664
  var v = ('' + input.value).trim();
638
665
  if (!v) { U.toast('Enter a key first'); return; }
@@ -643,9 +670,13 @@ var Views = (function () {
643
670
  };
644
671
  row.appendChild(valBtn);
645
672
  }
673
+ row.appendChild(confirmBtn);
646
674
  row.appendChild(cancelBtn);
647
675
  wrap.appendChild(row);
648
676
 
677
+ // DOWN from the field lands on Validate (or Confirm when there's no validator)
678
+ input.__navDOWN = function () { Focus.setFocus(valBtn || confirmBtn); return true; };
679
+
649
680
  s.appendChild(wrap);
650
681
  Focus.setScope(s, input);
651
682
 
@@ -690,6 +721,23 @@ var Views = (function () {
690
721
  return row;
691
722
  }
692
723
 
724
+ // Like subCycleRow but OK opens a scrollable list picker.
725
+ function subPickRow(caption, list, key) {
726
+ var row = U.el('div', 'addon-item focusable cfg-row');
727
+ var name = U.el('div', 'a-name');
728
+ function render() { name.textContent = caption + ': ' + labelFor(list, Player.getSubCfg()[key]); }
729
+ render();
730
+ row.appendChild(name);
731
+ row.appendChild(U.el('div', 'a-url', 'Press OK to choose'));
732
+ row.__onselect = function () {
733
+ pickList(caption, list, Player.getSubCfg()[key], function (v) {
734
+ var cfg = Player.getSubCfg(); cfg[key] = v; Player.setSubCfg(cfg);
735
+ render();
736
+ });
737
+ };
738
+ return row;
739
+ }
740
+
693
741
  // ================= SETTINGS (sectioned) =================
694
742
  var _settingsSection = 'menu';
695
743
 
@@ -825,7 +873,7 @@ var Views = (function () {
825
873
 
826
874
  function settingsSubtitles(wrap) {
827
875
  wrap.appendChild(U.el('h2', null, 'Subtitle Options'));
828
- wrap.appendChild(subCycleRow('Default language', SUB_LANGS, 'lang'));
876
+ wrap.appendChild(subPickRow('Default language', SUB_LANGS, 'lang'));
829
877
  wrap.appendChild(subCycleRow('Size', SUB_SIZES, 'size'));
830
878
  wrap.appendChild(subCycleRow('Style', SUB_STYLES, 'style'));
831
879
  wrap.appendChild(backRow());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuvio-tizen",
3
- "version": "1.8.9",
3
+ "version": "1.8.12",
4
4
  "description": "Nuvio-style Stremio-addon streaming client for Tizen 3.0+ Samsung TVs (TizenBrew app module).",
5
5
  "packageType": "app",
6
6
  "appName": "Nuvio",