Skip to content

Commit 5f52cb0

Browse files
authored
Merge pull request #63 from trip5/ehradio
2026.03.22
2 parents ea5d7d0 + 7d15d14 commit 5f52cb0

4 files changed

Lines changed: 52 additions & 29 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Documentation will be improved at some point... Until then, check this page and
2525
### 2026.03.22
2626
- [ehDP Library](https://github.com/trip5/ehDP) added
2727
- Device can be found using [eh Device Scanner](https://github.com/trip5/eh-Device-Scanner)
28+
- Grabbable aand hovered items fixed in playlist editor for mobile devices
2829
- Some major changes to the workflows that handle Releases and firmware generation
2930

3031
### 2026.03.18

data/www/dragpl.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,19 @@ document.addEventListener("dragend", (e) => {
143143
dragged = null;
144144
});
145145

146+
// Prevent browser context menu on long press
147+
document.addEventListener("contextmenu", (e) => {
148+
if (e.target.classList.contains('grabbable') || getLi(e.target)) {
149+
e.preventDefault();
150+
return false;
151+
}
152+
});
153+
146154
// Mobile/Touch Support
147155
document.addEventListener("touchstart", (e) => {
148156
if (e.target.classList.contains('grabbable')) {
157+
// Prevent text selection and context menu
158+
e.preventDefault();
149159
const touch = e.touches[0];
150160
startX = touch.clientX;
151161
startY = touch.clientY;

data/www/style.css

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ html, body { margin: 0; padding: 0; height: 100%; }
22
body { background: var(--main-bg-color); color: var(--main-text-color); font-family: Times, "Times New Roman", serif; font-size: 16px; }
33
*, *::before, *::after { box-sizing: border-box; scrollbar-width: thin; user-select: none; }
44
a { color: var(--accent-color); text-decoration: none; font-weight: bold }
5-
a:hover { text-decoration: underline }
5+
@media (hover: hover) and (pointer: fine) { /* mouse only */ a:hover { text-decoration: underline } }
66
ul, ol { list-style-type: none; margin: 0; padding: 0; }
77
h2 { text-align: center; padding-top: 10px; margin: 0 auto; text-transform: uppercase; font-weight: bold; font-size: 26px; color: var(--accent-color); }
88
h2.pagetitle { line-height: 48px; margin: 5px 0 5px 0 }
@@ -66,11 +66,18 @@ input[type=range] {
6666
/* PLAYER CONTROLS */
6767
.fb:active, .gb:active { position: relative; top: 2px; }
6868
.gb { width: 54px; height: 54px; cursor: pointer; border: var(--accent-color) 2.5px solid; border-radius: 50%;
69-
-webkit-tap-highlight-color: rgba(255, 255, 255, 0); stroke: var(--accent-color); display: flex; justify-content: center; align-items: center; }
69+
-webkit-tap-highlight-color: rgba(255, 255, 255, 0); stroke: var(--accent-color); display: flex; justify-content: center; align-items: center;
70+
-webkit-touch-callout: none; -webkit-user-select: none; user-select: none; touch-action: manipulation; }
7071
.gb.nb { border-color: transparent; }
71-
.gb:hover, .gb.active, #playerwrap.playing #playbutton { background-color: var(--accent-dark); border-color: var(--accent-color); }
72-
.gb:hover svg, .gb.active svg, #playerwrap.playing #playbutton svg{ stroke: var(--main-bg-color); fill: none; }
73-
.gb:hover svg.fill, .gb.active svg.fill{ fill: var(--main-bg-color); stroke: none; }
72+
@media (hover: hover) and (pointer: fine) { /* mouse only */
73+
.gb:hover, .fb:hover { background-color: var(--accent-dark); border-color: var(--accent-color); }
74+
.gb:hover svg { stroke: var(--main-bg-color); fill: none; }
75+
.gb:hover svg.fill { fill: var(--main-bg-color); stroke: none; }
76+
}
77+
.gb.active, #playerwrap.playing #playbutton { background-color: var(--accent-dark); border-color: var(--accent-color); }
78+
.gb.active svg, #playerwrap.playing #playbutton svg { stroke: var(--main-bg-color); fill: none; }
79+
.gb.active svg.fill { fill: var(--main-bg-color); stroke: none; }
80+
.gb:focus, .fb:focus { outline: none; }
7481
.gb svg{ width: 28px; stroke: var(--accent-color); stroke-width: 2px; fill: none; stroke-linejoin: round; stroke-linecap: round; }
7582
.gb.nb svg { width: 36px; }
7683
.gb.active.nb svg { width: 32px; }
@@ -108,8 +115,10 @@ input[type=range] {
108115
#playerwrap.playing #bitinfo { opacity: 1; }
109116
.formbuttons { display: flex; flex-wrap: wrap; justify-content: space-around; max-width: 100%; width: 100%; margin: 0 auto; margin-top: 20px; }
110117
.fb { padding: 8px 22px; font-size: 16px; border: var(--accent-color) 2px solid; font-weight: normal; border-radius: 20px; cursor: pointer;
111-
text-align: center; min-width: 100px; margin-left: 8px; margin-right: 8px; text-transform: uppercase; color: var(--accent-color); background: var(--odd-bg-color); }
112-
.fb:hover, .fb.hl { background: var(--accent-dark); color: var(--accent-text-color); text-decoration: none; }
118+
text-align: center; min-width: 100px; margin-left: 8px; margin-right: 8px; text-transform: uppercase; color: var(--accent-color); background: var(--odd-bg-color);
119+
touch-action: manipulation; }
120+
@media (hover: hover) and (pointer: fine) { /* mouse only */ .fb:hover { background: var(--accent-dark); color: var(--accent-text-color); text-decoration: none; } }
121+
.fb.hl { background: var(--accent-dark); color: var(--accent-text-color); text-decoration: none; }
113122
.fb.done { margin-left: calc(50%); transform: translateX(-50%); margin-top: 20px; margin-bottom: 10px; max-width: 140px; }
114123
#playlist {
115124
position: relative; scroll-behavior: smooth; scrollbar-color: var(--accent-dark) var(--main-bg-color); overflow: auto; overflow-y: auto; border: solid 1px var(--accent-color); flex: 1 1 auto; height: 0px; width: 100%;
@@ -120,7 +129,7 @@ input[type=range] {
120129
#playlist li span.count { display: flex; flex-direction: column; justify-content: center; padding: 0 10px; text-align: right; font-size: 14px; vertical-align: middle; }
121130
#playlist li span { color: var(--accent-dark); }
122131
#playlist li:nth-child(odd) { background: var(--odd-bg-color); }
123-
#playlist li:hover { color: var(--main-text-color); background: var(--playlist-hover); }
132+
@media (hover: hover) and (pointer: fine) { /* mouse only */ #playlist li:hover { color: var(--main-text-color); background: var(--playlist-hover); } }
124133
#playlist li.active { background: var(--accent-dark); }
125134
#playlist li.active span { color: var(--accent-text-color); }
126135
#pleditorwrap { position: absolute; background: var(--main-bg-color); top: 120px; right: 0; left: 0; bottom: 0; padding: 5px 5px 10px 5px; overflow-y: auto; z-index: 50; }
@@ -152,7 +161,8 @@ input[type=range] {
152161
.pleurl { flex: 1; color: var(--main-hl-color)!important; }
153162
.pleovol { width: 53px!important; font-size: 16px!important; }
154163
.pleitem span.pleplay { width: 28px!important; height: 28px; text-indent: -1px; font-size: 12px!important; cursor: pointer; color: var(--main-text-color); border: transparent 2px solid; border-radius: 50%; margin: 2px; }
155-
.pleitem span.pleplay:hover, .pleitem.active span.pleplay { background: var(--accent-dark)!important; color: var(--main-bg-color); border-color: var(--accent-color); }
164+
@media (hover: hover) and (pointer: fine) { /* mouse only */ .pleitem span.pleplay:hover { background: var(--accent-dark)!important; color: var(--main-bg-color); border-color: var(--accent-color); } }
165+
.pleitem.active span.pleplay { background: var(--accent-dark)!important; color: var(--main-bg-color); border-color: var(--accent-color); }
156166
.pleitem.active input.plename { color: var(--accent-color); }
157167
.pleitem.dragging { opacity: 0.5; filter: grayscale(1); }
158168
.pleitem.drag-over-above { border-top: 4px solid var(--accent-color)!important; }
@@ -166,7 +176,7 @@ input[type=range] {
166176
#settingswrap::-webkit-scrollbar-thumb { background: var(--section-border); }
167177
.navigation { display: flex; justify-content: space-evenly; margin: 0 20px 14px 0; }
168178
.navitem { text-transform: lowercase; cursor: pointer; color: var(--main-text-color); }
169-
.navitem:hover { text-decoration: underline; color: var(--accent-color); }
179+
@media (hover: hover) and (pointer: fine) { /* mouse only */ .navitem:hover { text-decoration: underline; color: var(--accent-color); } }
170180
section { border: var(--section-border) 1px solid; border-radius: 10px; box-sizing: border-box; padding: 20px 20px 30px 20px; margin: 10px 0 30px 0; width: 100%;
171181
background-image: linear-gradient(var(--main-bg-color), var(--section-gradient)); position: relative; scroll-margin-top: 20px; }
172182
section .title { width: auto; margin-top: -34px; padding: 4px 0 30px 0; color: #aaa; text-align: center; }
@@ -177,11 +187,12 @@ section .title span { padding: 4px 8px; background: var(--main-bg-color); font-w
177187
.flex-row { display: flex; justify-content: space-between; align-items: flex-end; padding: 7px 0; box-sizing: border-box; }
178188
.flex-row.center { justify-content: center; }
179189
.flex-row.last { justify-content: space-evenly; padding: 20px 20px 0 20px; }
180-
section .reset { position: absolute; cursor: pointer; background-color: var(--main-bg-color); border: var(--section-border) 2px solid; border-radius: 50%;
181-
width: 28px; height: 28px; right: 14px; top: -16px; }
182-
section .reset:hover { background-color: var(--section-border); }
183-
section .reset svg.fill{ fill: var(--section-border); stroke: none; width: 22px; }
184-
section .reset:hover svg.fill{ fill: var(--main-bg-color); }
190+
section .reset { position: absolute; cursor: pointer; background-color: var(--main-bg-color); border: var(--section-border) 2px solid; border-radius: 50%; width: 28px; height: 28px; right: 14px; top: -16px; }
191+
@media (hover: hover) and (pointer: fine) { /* mouse only */
192+
section .reset:hover { background-color: var(--section-border); }
193+
section .reset:hover svg.fill { fill: var(--main-bg-color); }
194+
}
195+
section .reset svg.fill{ fill: var(--section-border); stroke: none; width: 22px; }
185196
.inputwrap { flex: 1; position: relative; padding: 0px 1% 0px 1%; }
186197
.inputwrap.pad { padding-top: 20px; }
187198
.inputwrap.center { display: flex; flex-direction: column; align-items: center; }
@@ -193,23 +204,23 @@ section .reset:hover svg.fill{ fill: var(--main-bg-color); }
193204
.searchtitle1 { margin: 0; padding: 0 8px; font-size: 26px; font-weight: bold; text-align: center; position: absolute; left: 50%; top: 0; transform: translateX(-50%); width: max-content; right: 0; z-index: 2; background: transparent; }
194205
.searchtitle2 { margin: 0; padding: 7.5 0px 0px 8px; font-size: 13px; font-weight: bold; text-align: right; float: right; display: block; z-index: 1; background: transparent; }
195206
.searchtitle2 a { cursor: pointer; color: var(--main-text-color); }
196-
.searchtitle2 a:hover { color: var(--accent-color); text-decoration: underline; }
207+
@media (hover: hover) and (pointer: fine) { /* mouse only */ .searchtitle2 a:hover { color: var(--accent-color); text-decoration: underline; } }
197208
#searchcontent, #curatedcontent { display: flex; max-width: 580px; margin: 0 auto; flex-direction: column; align-items: center; padding: 4px; height: 100%; box-sizing: border-box; position: relative; padding-top: 2px; padding-bottom: 2px; }
198209
#searches { display: flex; flex-direction: column; width: 100%; gap: 4px; margin-bottom: 4px; }
199210
.search-row { display: flex; align-items: center; gap: 2px; }
200211
.search-row .searchtextinput { flex-grow: 1; }
201212
.search-row .searchtextinput.select { flex-grow: 0; }
202213
table, tr, td { margin: 0; padding: 0; }
203214
.searchbutton { font-family: Helvatica, Arial, Sans; padding: 4px; font-size: 18px; border: var(--accent-color) 2px solid; font-weight: normal; box-sizing: border-box; border-radius: 20px; cursor: pointer; text-align: center; min-width: 120px; text-transform: uppercase; color: var(--accent-color); background: var(--odd-bg-color); }
204-
.searchbutton:hover { background: var(--accent-dark); color: var(--accent-text-color); text-decoration: none; }
215+
@media (hover: hover) and (pointer: fine) { /* mouse only */ .searchbutton:hover { background: var(--accent-dark); color: var(--accent-text-color); text-decoration: none; } }
205216
.searchbutton:active { position: relative; top: 2px; }
206217
.quicksearches { display: flex; justify-content: space-evenly; width: 100%; padding: 0 2px; margin: 0 0 4px 0; box-sizing: border-box; }
207218
.quicksearchtable { width: 100%; padding: 0; margin: 0; text-align: center; border-spacing: 1px; }
208219
.quicksearch { text-transform: lowercase; cursor: pointer; color: var(--main-text-color); width: 100%; text-align: center; border: none; background-color: var(--main-bg-color); font-family: Times, "Times New Roman", serif; font-size: 16px; padding: 0px; margin: 0px; min-width: 80px; }
209-
.quicksearch:hover { text-decoration: underline; color: var(--accent-color); }
220+
@media (hover: hover) and (pointer: fine) { /* mouse only */ .quicksearch:hover { text-decoration: underline; color: var(--accent-color); } }
210221
.searchbutton.search.plus, .searchbutton.search.minus { margin-top: 0px; width: 22px; max-width: 22px; min-width: 22px; height: 22px; font-size: 22px; font-weight: bold; display: flex; align-items: center; justify-content: center; }
211222
.searchbutton.search.plus svg, .searchbutton.search.minus svg { width: 16px; height: 16px; stroke: var(--accent-color); stroke-width: 4px; fill: none; stroke-linecap: round; stroke-linejoin: round; }
212-
.searchbutton.search.plus:hover svg, .searchbutton.search.minus:hover svg { stroke: var(--accent-text-color); }
223+
@media (hover: hover) and (pointer: fine) { /* mouse only */ .searchbutton.search.plus:hover svg, .searchbutton.search.minus:hover svg { stroke: var(--accent-text-color); } }
213224
.sort-row { font-family: Times, "Times New Roman", serif; font-size: 16px; font-weight: bold; display: flex; justify-content: space-between; width: 100%; margin: 4px 0 4px 0; }
214225
.sort-row label { padding: 0 2px; margin: 0; cursor: pointer; }
215226
.sort-row input[type="radio"] { margin-right: 10px; cursor: pointer; }
@@ -231,7 +242,7 @@ table.stations td.info table td.codec { text-align: left; }
231242
table.stations td.info table td.bitrate { text-align: right; }
232243
table.stations .searchbutton { max-width: 46px; min-width: 46px; height: 46px; text-align: center; display: flex; align-items: center; margin: 1px 15px 1px 5px; }
233244
table.stations .searchbutton svg { stroke: var(--accent-color); stroke-width: 2px; fill: none; stroke-linecap: round; stroke-linejoin: round; fill: var(--accent-color);}
234-
table.stations .searchbutton:hover svg { stroke: var(--accent-text-color); fill: none; fill: var(--accent-text-color); }
245+
@media (hover: hover) and (pointer: fine) { /* mouse only */ table.stations .searchbutton:hover svg { stroke: var(--accent-text-color); fill: none; fill: var(--accent-text-color); } }
235246
table.stations .searchbutton.addtoplaylist { margin-left: auto; }
236247
table.stations .importantmessage { color: var(--accent-color) !important; font-size: 24px !important; font-style: italic !important; background: transparent !important; }
237248
#pageNav { display: flex; justify-content: space-between; align-items: center; width: 100%; padding: 0 2px; margin: 0 0 4px 0; }
@@ -266,7 +277,7 @@ table.stations .importantmessage { color: var(--accent-color) !important; font-s
266277
-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
267278
#updateform label input { position: absolute; cursor: pointer; opacity: 0; z-index: 5; width: 100%; margin: 0 0 0 -40px; height: 29px; }
268279
.checkmark { position: absolute; top: 0; left: 0; height: 28px; width: 28px; background-color: var(--odd-bg-color); border-radius: 50%; border: var(--accent-color) 2px solid; }
269-
#updateform label:hover input ~ .checkmark { background-color: var(--odd-bg-color); }
280+
@media (hover: hover) and (pointer: fine) { /* mouse only */ #updateform label:hover input ~ .checkmark { background-color: var(--odd-bg-color); } }
270281
#updateform label input:checked ~ .checkmark { background-color: var(--odd-bg-color); }
271282
.checkmark:after { content: ""; position: absolute; display: none; }
272283
#updateform label input:checked ~ .checkmark:after { display: block; }
@@ -275,7 +286,7 @@ table.stations .importantmessage { color: var(--accent-color) !important; font-s
275286
#updateform input[type=file] {color: var(--main-hl-color); font-size: 16px; font-family: Times, "Times New Roman", serif; flex: 1; }
276287
#updateform input[type=file]::file-selector-button { padding: 8px 8px; font-size: 18px; border: var(--accent-color) 2px solid; font-weight: normal; box-sizing: border-box;
277288
border-radius: 20px; cursor: pointer; text-align: center; min-width: 120px; margin-right: 20px; text-transform: uppercase; color: var(--accent-color); background: var(--odd-bg-color); font-family: Times, "Times New Roman", serif; }
278-
#updateform input[type=file]::file-selector-button:hover { color: var(--odd-bg-color); background: var(--accent-color); }
289+
@media (hover: hover) and (pointer: fine) { /* mouse only */ #updateform input[type=file]::file-selector-button:hover { color: var(--odd-bg-color); background: var(--accent-color); } }
279290
#updateform .fb { margin: 0; font-family: Times, "Times New Roman", serif; }
280291
#updateprogress { background-color: var(--odd-bg-color); border: var(--accent-color) 2px solid; height: 30px; border-radius: 15px; width: 100%; margin: 0; overflow: hidden; }
281292
#updateprogress::-webkit-progress-bar { overflow: hidden; background-color: var(--odd-bg-color); border-radius: 15px; }
@@ -298,8 +309,12 @@ table.stations .importantmessage { color: var(--accent-color) !important; font-s
298309
.irbutton svg { width: 20px; fill: var(--main-hl-color); stroke: none; }
299310
.irbutton.blue { background-color: #2648a9; border-color: #3356ba; color: var(--main-hl-color); }
300311
.irbutton.red { background-color: #d31b20; border-color: #e53a3e; color: var(--main-hl-color); }
301-
.irbutton:hover, .irbutton:active, .irbutton.active { background-color: var(--accent-color); border-color: var(--accent-color); color: var(--main-bg-color); }
302-
.irbutton:hover svg, .irbutton:active svg, .irbutton.active svg { fill: var(--main-bg-color); }
312+
@media (hover: hover) and (pointer: fine) { /* mouse only */
313+
.irbutton:hover { background-color: var(--accent-color); border-color: var(--accent-color); color: var(--main-bg-color); }
314+
.irbutton:hover svg { fill: var(--main-bg-color); }
315+
}
316+
.irbutton:active, .irbutton.active { background-color: var(--accent-color); border-color: var(--accent-color); color: var(--main-bg-color); }
317+
.irbutton:active svg, .irbutton.active svg { fill: var(--main-bg-color); }
303318
#irform { flex: 1; text-align: center; padding-left: 20px; }
304319
#irstartrecord h3 { font-size: 20px; font-weight: bold; color: var(--accent-color); }
305320
#irrecordtitle { padding-left: 42px; }
@@ -308,7 +323,7 @@ table.stations .importantmessage { color: var(--accent-color) !important; font-s
308323
.irrecordrow { display: flex; margin-bottom: 20px; position: relative; }
309324
.irradio { width: 42px; cursor: pointer; display: flex; align-items: center; }
310325
.irradio span { position: relative; height: 28px; width: 28px; background-color: var(--main-bg-color); border-radius: 50%; border: var(--accent-color) 2px solid; margin: 4px 0; }
311-
.irradio span:hover { background-color: var(--odd-bg-color); }
326+
@media (hover: hover) and (pointer: fine) { /* mouse only */ .irradio span:hover { background-color: var(--odd-bg-color); } }
312327
.irradio.active span { background-color: var(--odd-bg-color); }
313328
.irradio span:after { content: ""; position: absolute; display: none; }
314329
.irradio.active span:after { display: block; }

src/core/options.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ Use this tool to setup connections: https://trip5.github.io/ehRadio_myoptions/ge
540540
#endif
541541
#endif
542542
#ifndef BUFLEN
543-
#define BUFLEN 170 // seems safe... a lot of multipliers exist in the code...
543+
#define BUFLEN 170 // 170 seems safe... a lot of multipliers exist in the code...
544544
#endif
545545

546546
/* This bit will actually do something but needs to be handled a different way (configurable would be better!) */
@@ -746,9 +746,6 @@ Use this tool to setup connections: https://trip5.github.io/ehRadio_myoptions/ge
746746
#ifndef EHDP
747747
#define EHDP true
748748
#endif
749-
#ifndef AUDIO_PREVIEW_IN_BROWSER
750-
#define AUDIO_PREVIEW_IN_BROWSER false
751-
#endif
752749
#ifndef SOFTAP_REBOOT_DELAY
753750
#define SOFTAP_REBOOT_DELAY 0
754751
#elif (SOFTAP_REBOOT_DELAY < 0) || (SOFTAP_REBOOT_DELAY > 20)

0 commit comments

Comments
 (0)