neon_arch commited on
Commit
d659589
2 Parent(s): e7701e1 3cbe1cb

Merge pull request #88 from sam-sunder/rolling

Browse files
public/static/settings.js ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ UI: Method for selecting all search engines
3
+
4
+ This function is called when user click on
5
+ `select all` and `deselect all` toogle element.
6
+
7
+ - If select all is pressed toggle all options and insert all value
8
+ joined with comma to input which is saved in cookie.
9
+ then changes text to `deselect all`.
10
+ eg value: 'ddg,searx,'
11
+
12
+ - If deselect all is pressed uncheck all options and insert empty
13
+ value to input which is saved in cookie.
14
+ */
15
+ function selectAllHandler(elem) {
16
+ let span = elem.parentElement.querySelector("span");
17
+ let mainInput = document.getElementsByName("searchEng")[0];
18
+ let prevStateSelectAll = span.innerText == "Select all" ? true : false;
19
+ document.querySelectorAll(".searchEng-elem").forEach((engine) => {
20
+ if (prevStateSelectAll) {
21
+ engine.querySelector('input[type="checkbox"]').checked = true;
22
+ } else {
23
+ engine.querySelector('input[type="checkbox"]').checked = false;
24
+ }
25
+ });
26
+ if (prevStateSelectAll) {
27
+ let getValues = () => {
28
+ let value = "";
29
+ document
30
+ .querySelectorAll('[data-isCheckbox]:not([data-value="all"])')
31
+ .forEach((elem) => {
32
+ value += elem.getAttribute("data-value") + ",";
33
+ });
34
+ return value;
35
+ };
36
+ mainInput.value = getValues();
37
+ } else {
38
+ mainInput.value = "";
39
+ }
40
+ span.innerText = prevStateSelectAll ? "Deselect all" : "Select all";
41
+ }
42
+
43
+ /*
44
+ UI: Filter settings as per category
45
+
46
+ There are two elements one is `category` and `detail`.
47
+ Category contains `data-id` when a user click it
48
+ we need to show detail element having
49
+ `data-detailId` whose value is same as `data-id`.
50
+
51
+ When a user clicks on a category on sidebar, view
52
+ settings containing `data-id` of sidebar element's `data-detailId`
53
+ and hide other settings
54
+
55
+ - if `all` is clicked then show all settings.
56
+ */
57
+ document.querySelectorAll(".settings-sidebar .set-name").forEach((filter) => {
58
+ let target = filter.getAttribute("data-detailId");
59
+ filter.addEventListener("click", () => {
60
+ try {
61
+ document.querySelector(".set-name.active").classList.remove("active");
62
+ } catch (e) {}
63
+ filter.classList.add("active");
64
+ if (target == "all") {
65
+ document.querySelectorAll(".set-item").forEach((elem) => {
66
+ elem.style.display = "block";
67
+ });
68
+ return;
69
+ }
70
+ document
71
+ .querySelectorAll('.set-item[data-id="' + target + '"]')
72
+ .forEach((elem) => {
73
+ elem.style.display = "block";
74
+ });
75
+ document
76
+ .querySelectorAll('.set-item:not([data-id="' + target + '"])')
77
+ .forEach((elem) => {
78
+ elem.style.display = "none";
79
+ });
80
+ });
81
+ });
82
+
83
+
84
+ /*
85
+ This function is called when a user click on submit button
86
+ it validates all user inputs and saves to a cookie.
87
+
88
+ - if input having `required` attr and is empty it generates a
89
+ error text and insert above the setting element
90
+
91
+ - else store setttings to a cookie.
92
+ */
93
+ function submitSettings() {
94
+ let form = document.settings;
95
+ let stopProceeding = false;
96
+ document.querySelectorAll(".errTxt").forEach((e) => e.remove());
97
+ for (let i = 0; i < form.elements.length; i++) {
98
+ let input = form.elements[i];
99
+ if (input.value == "" && input.hasAttribute("required")) {
100
+ stopProceeding = true;
101
+ let elem = input.parentElement.querySelector("[takeInput]");
102
+ let errTxt = document.createElement("p");
103
+ errTxt.classList.add("errTxt");
104
+ errTxt.innerText = "This setting can't be empty!!";
105
+ elem.classList.add("invalid");
106
+ elem.parentElement.insertBefore(errTxt, elem);
107
+ let sidebarElement = input.closest(".set-item").getAttribute("data-id");
108
+ document
109
+ .querySelector(
110
+ `.settings-sidebar .set-name[data-detailId="${sidebarElement}`
111
+ )
112
+ .click();
113
+ stopProceeding = true;
114
+ }
115
+ }
116
+ if (!stopProceeding) {
117
+ var expiration_date = new Date();
118
+ expiration_date.setFullYear(expiration_date.getFullYear() + 1);
119
+ let formData = new FormData(document.querySelector("form"));
120
+ for (var [key, value] of formData.entries()) {
121
+ document.cookie = `${key}=${value}; expires=${expiration_date.toUTCString()}`;
122
+ }
123
+ } else {
124
+ return false;
125
+ }
126
+ // On settings saved successfully
127
+ alert("Settings saved succssfully!");
128
+ window.location.reload();
129
+ }
130
+
131
+
132
+ /*
133
+ This function will be called on page ready.
134
+ it iterates over saved cookies and if cookie name is
135
+ in the list of valid cookies then load it.
136
+
137
+ - if cookie is searchEng(type=toggle/checkbox) we deselect
138
+ all checkboxes and select those which are stored in cookie.
139
+
140
+ - if cookie is of type `select` we deselect default selected
141
+ option and then select option which is stored in cookie.
142
+ */
143
+ function loadUserSettings() {
144
+ let inputs = ["searchEng", "theme", "color-sch"];
145
+ var keyValuePairs = document.cookie.split(";");
146
+ for (var i = 0; i < keyValuePairs.length; i++) {
147
+ var name = keyValuePairs[i].substring(0, keyValuePairs[i].indexOf("="));
148
+ var value = keyValuePairs[i].substring(keyValuePairs[i].indexOf("=") + 1);
149
+ name = name.trim();
150
+ if (!inputs.includes(name)) {
151
+ continue;
152
+ }
153
+ let input = document.getElementsByName(name)[0];
154
+ input.value = value;
155
+ if (name == "searchEng") {
156
+ // Unload all checked engines
157
+ document
158
+ .querySelectorAll(".searchEng-elem input[type=checkbox]")
159
+ .forEach((e) => {
160
+ e.checked = false;
161
+ });
162
+ value = value.replace(" ", "");
163
+ value.split(",").forEach((val) => {
164
+ if (!val) {
165
+ return;
166
+ }
167
+ document
168
+ .querySelector(`[data-isCheckbox][data-value="${val}"]`)
169
+ .parentElement.querySelector("input").checked = true;
170
+ });
171
+ } else {
172
+ // Unload all selected options
173
+ document
174
+ .querySelector(
175
+ `[data-input="${name}"] .options span[data-value="${value}"]`
176
+ )
177
+ .removeAttribute("selected");
178
+ singleSelectClickHandler(
179
+ document.querySelector(`.options span[data-value="${value}"]`)
180
+ );
181
+ }
182
+ }
183
+ }
184
+
185
+ // Code where settings are loaded from cookie.
186
+ loadUserSettings();
public/static/themes/simple.css CHANGED
@@ -263,41 +263,320 @@ footer {
263
 
264
  /* Styles for the about page */
265
 
266
- .about-container article{
267
- font-size: 1.5rem;
268
- color:var(--fg);
269
- padding-bottom: 10px;
270
- }
271
-
272
- .about-container article h1{
273
- color: var(--2);
274
- font-size: 2.8rem;
275
- }
276
-
277
- .about-container article div{
278
- padding-bottom: 15px;
279
- }
280
-
281
- .about-container a{
282
- color:var(--3);
283
- }
284
-
285
- .about-container article h2{
286
- color: var(--3);
287
- font-size: 1.8rem;
288
- padding-bottom: 10px;
289
- }
290
-
291
- .about-container p{
292
- color:var(--fg);
293
- font-size: 1.6rem;
294
- padding-bottom: 10px;
295
- }
296
-
297
- .about-container h3{
298
- font-size: 1.5rem;
299
- }
300
-
301
- .about-container {
302
- width: 80%;
303
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
 
264
  /* Styles for the about page */
265
 
266
+ .about-container article{
267
+ font-size: 1.5rem;
268
+ color:var(--fg);
269
+ padding-bottom: 10px;
270
+ }
271
+
272
+ .about-container article h1{
273
+ color: var(--2);
274
+ font-size: 2.8rem;
275
+ }
276
+
277
+ .about-container article div{
278
+ padding-bottom: 15px;
279
+ }
280
+
281
+ .about-container a{
282
+ color:var(--3);
283
+ }
284
+
285
+ .about-container article h2{
286
+ color: var(--3);
287
+ font-size: 1.8rem;
288
+ padding-bottom: 10px;
289
+ }
290
+
291
+ .about-container p{
292
+ color:var(--fg);
293
+ font-size: 1.6rem;
294
+ padding-bottom: 10px;
295
+ }
296
+
297
+ .about-container h3{
298
+ font-size: 1.5rem;
299
+ }
300
+
301
+ .about-container {
302
+ width: 80%;
303
+ }
304
+
305
+ /* css for settings page t */
306
+ .settings {
307
+ margin: 2rem;
308
+ width: 80%;
309
+ height: 100%;
310
+ color: var(--fg);
311
+ }
312
+
313
+ .settings h1 {
314
+ color: var(--2);
315
+ font-size: 2.5rem;
316
+ }
317
+
318
+
319
+ .settings hr {
320
+ border-color: var(--3);
321
+ margin: .3rem 0 1rem 0;
322
+ }
323
+
324
+ .settings-view {
325
+ display: flex;
326
+ flex: 1 0 auto;
327
+ margin: 1.5rem 0;
328
+ }
329
+
330
+ .settings-sidebar {
331
+ width: 25%;
332
+ height: 100%;
333
+ }
334
+
335
+ .settings-sidebar .set-name {
336
+ cursor: pointer;
337
+ font-size: 2rem;
338
+ display: block;
339
+ margin-right: .5rem;
340
+ margin-left: -.7rem;
341
+ padding: .7rem;
342
+ border-radius: 5px;
343
+ font-weight: bold;
344
+ margin-bottom: .5rem;
345
+ }
346
+
347
+ .settings-sidebar .set-name:hover, .settings-sidebar .set-name.active {
348
+ background-color: rgba(255, 255, 255, 0.15);
349
+
350
+ }
351
+
352
+ .settings-detail {
353
+ border-left: 1.5px solid var(--3);
354
+ padding-left: 3rem;
355
+ }
356
+
357
+ .settings-detail .set-item {
358
+ margin: 2rem 0;
359
+ margin-top: 0;
360
+ }
361
+
362
+ .settings-detail .set-name {
363
+ font-size: 2rem;
364
+ font-weight: bold;
365
+ color: var(--4)
366
+ }
367
+
368
+ .settings-detail .set-desc {
369
+ font-size: 1.5rem;
370
+ margin-bottom: .5rem;
371
+ }
372
+
373
+ /* css for custom select */
374
+ .custom-select, .options {
375
+ font-size: 1.5rem;
376
+ background-color: var(--bg);
377
+ width: 250px;
378
+ padding: 1rem 1.7rem;
379
+ border-radius: 7px;
380
+ }
381
+
382
+ .custom-select {
383
+ position: relative;
384
+ vertical-align: middle;
385
+ margin: .7rem 0;
386
+ }
387
+
388
+ .custom-select.invalid {
389
+ border: 1px solid red;
390
+ }
391
+
392
+ .custom-select svg {
393
+ float: right;
394
+ }
395
+
396
+ .options {
397
+ display: none;
398
+ position: absolute;
399
+ left: 0;
400
+ margin-top: 1.3rem;
401
+ width: 100%;
402
+ padding: .7rem 1rem;
403
+ cursor: pointer;
404
+ z-index: 3;
405
+ max-height: 15rem;
406
+ overflow-y: auto;
407
+ }
408
+
409
+ .options span {
410
+ display: block;
411
+ padding: 1rem;
412
+ width: 100%;
413
+ border-radius: 5px;
414
+ vertical-align: middle;
415
+ }
416
+
417
+ .options span:hover {
418
+ background-color: var(--1);
419
+ }
420
+
421
+ .selected-multiple-option {
422
+ padding: .8rem;
423
+ border-radius: 5px;
424
+ background-color: var(--bg);
425
+ margin: .5rem .3rem;
426
+ }
427
+
428
+ .selected-multiple-option svg {
429
+ width: 1.3rem;
430
+ height: 1.3rem;
431
+ vertical-align: middle;
432
+ margin-bottom: .5rem;
433
+ cursor: pointer;
434
+ }
435
+
436
+ .select-multiple-show {
437
+ margin: 1rem 0;
438
+ font-size: 1.5rem;
439
+ }
440
+
441
+ .underlined-text {
442
+ font-size: 1.7rem;
443
+ cursor: pointer;
444
+ margin-bottom: .5rem;
445
+ display: block;
446
+ }
447
+
448
+ .settings .submit-btn {
449
+ padding: 1rem 2rem;
450
+ font-size: 1.5rem;
451
+ background: var(--3);
452
+ color: var(--bg);
453
+ border-radius: .5rem;
454
+ border: 2px solid transparent;
455
+ font-weight: bold;
456
+ transition: all .1s ease-out;
457
+ cursor: pointer;
458
+ box-shadow: 5px 5px;
459
+ }
460
+
461
+ .settings .submit-btn:active {
462
+ outline: none;
463
+ box-shadow: none;
464
+ translate: 5px 5px;
465
+ }
466
+
467
+ /* Css for error text */
468
+
469
+ .errTxt {
470
+ color: white;
471
+ background: red;
472
+ padding: .5rem;
473
+ border-radius: 5px;
474
+ font-size: 1.3rem;
475
+ width: max-content;
476
+ }
477
+
478
+ /* Css for toggle element */
479
+
480
+ label,
481
+ label::before,
482
+ label::after {
483
+ transition: 200ms all ease-in-out 50ms;
484
+ box-sizing: border-box;
485
+ backface-visibility: hidden;
486
+ }
487
+
488
+ input[type="checkbox"] {
489
+ display: none;
490
+ }
491
+
492
+ /*Button is :CHECKED*/
493
+
494
+ input[type="checkbox"]:checked ~ div[data-isCheckbox] {
495
+ background: rgba(73,168,68,1);
496
+ box-shadow: 0 0 2px rgba(73,168,68,1);
497
+ }
498
+
499
+ input[type="checkbox"]:checked ~ div[data-isCheckbox] label {
500
+ left: 25px;
501
+ transform: rotate(360deg);
502
+ }
503
+
504
+
505
+ /*shared*/
506
+
507
+ div[data-isCheckbox],
508
+ label {
509
+ border-radius: 50px;
510
+ }
511
+
512
+
513
+ /*'un':checked state*/
514
+
515
+ div[data-isCheckbox] {
516
+ height: 25px;
517
+ width: 50px;
518
+ background: rgba(43, 43, 43, 1);
519
+ position: relative;
520
+ box-shadow: 0 0 2px rgba(43,43,43,1);
521
+
522
+ }
523
+
524
+ label {
525
+ height: 20px;
526
+ width: 20px;
527
+ background: rgba(255, 255, 255, 1);
528
+ position: absolute;
529
+ top: 3px;
530
+ left: 3px;
531
+ cursor: pointer;
532
+ }
533
+
534
+ label::before {
535
+ content: '';
536
+ height: 15px;
537
+ width: 3px;
538
+ position: absolute;
539
+ top: calc(50% - 8px);
540
+ left: calc(50% - 1.5px);
541
+ transform: rotate(45deg);
542
+ }
543
+
544
+ label::after {
545
+ content: '';
546
+ height: 3px;
547
+ width: 15px;
548
+ position: absolute;
549
+ top: calc(50% - 2.5px);
550
+ left: calc(50% - 8px);
551
+ transform: rotate(45deg);
552
+ }
553
+
554
+ label::before,
555
+ label::after{
556
+ background: rgba(43,43,43,1);
557
+ border-radius: 5px;
558
+ }
559
+
560
+ /* pesduo class on toggle */
561
+
562
+ input[type="checkbox"]:checked ~ div label::before{
563
+ height: 15px;
564
+ top: calc(55% - 8px);
565
+ left: calc(60% - 2px);
566
+ background: rgba(73,168,68,1);
567
+ }
568
+
569
+ input[type="checkbox"]:checked ~ div label::after{
570
+ width: 7px;
571
+ top: calc(95% - 7px);
572
+ left: calc(22.5% - 2px);
573
+ background: rgba(73,168,68,1);
574
+ }
575
+
576
+ .searchEng-elem {
577
+ display: flex;
578
+ gap: 3rem;
579
+ align-items: center;
580
+ font-size: 1.5rem;
581
+ margin: 1rem 0;
582
+ }
public/static/ui_plugins.js ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Select plugin
3
+ Note: Only for single select option
4
+ Usage example:
5
+ ```
6
+ <input name="theme" disabled style="display: none;" required></input>
7
+ <div class="custom-select" tabindex="0" data-input="theme" data-default="Select" takeInput>
8
+ Svg Icon here
9
+ <div class="options">
10
+ <span data-value="simple">Simple</span>
11
+ </div>
12
+ </div>
13
+ ```
14
+ */
15
+
16
+ let svg_tick = `
17
+ <svg fill="currentColor" height="1.5rem" width="1.5rem" viewBox="0 0 490 490" xml:space="preserve">
18
+ <g id="SVGRepo_iconCarrier">
19
+ <polygon points="452.253,28.326 197.831,394.674 29.044,256.875 0,292.469 207.253,461.674 490,54.528 "></polygon>
20
+ </g>
21
+ </svg>`;
22
+
23
+ function toggleSelectOptions(elem, state) {
24
+ elem.classList.remove("invalid");
25
+ try { elem.parentElement.querySelector('.errTxt').remove();} catch (error) {}
26
+ let options = elem.querySelector('.options');
27
+ const pos = elem.getBoundingClientRect();
28
+ const windowWidth = document.getElementsByTagName("body")[0].clientHeight;
29
+ if(pos.y + 250 > windowWidth) {
30
+ options.style.bottom = '40px';
31
+ } else { options.style.bottom = null }
32
+ options.style.display = state != 'close' ? getComputedStyle(options).display == 'none' ? 'block': 'none' : 'none';
33
+ }
34
+
35
+ let selectElements = document.querySelectorAll('.custom-select').forEach(element => {
36
+ let value = element.getAttribute('data-default')
37
+ element.childNodes[0].nodeValue = value;
38
+ element.querySelector(`.options span[data-value="${value.toLowerCase()}"]`).
39
+ innerHTML = `${value} ${svg_tick}`;
40
+ element.addEventListener('click', (e) => {if (e.target === element) toggleSelectOptions(element)});
41
+ element.addEventListener('focusout', (e) => {if (e.target === element) toggleSelectOptions(element, 'close')});
42
+ });
43
+
44
+ function singleSelectClickHandler(elem) {
45
+ let selectDiv = elem.closest('.custom-select');
46
+ let selectedOption = selectDiv.querySelector('span[selected]');
47
+ let input = document.querySelector(`[name="${selectDiv.getAttribute('data-input')}"]`);
48
+ if (!elem.hasAttribute('selected')) {
49
+ if (selectedOption != null) {
50
+ selectedOption.removeAttribute('selected');
51
+ selectedOption.querySelector('svg').remove();
52
+ }
53
+ elem.setAttribute('selected', '');
54
+ elem.innerHTML = `${elem.innerText} ${svg_tick}`
55
+ // Code where value is inserted to input
56
+ input.value = elem.getAttribute('data-value') ? elem.getAttribute('data-value') : '';
57
+ selectDiv.childNodes[0].nodeValue = elem.innerText;
58
+ } else {
59
+ elem.removeAttribute('selected');
60
+ elem.querySelector('svg').remove();
61
+ selectDiv.childNodes[0].nodeValue = selectDiv.getAttribute('data-defaultIfNone');
62
+
63
+ input.value = "";
64
+ }
65
+ selectDiv.blur();
66
+ }
67
+
68
+ let singleSelectOptions = document.querySelectorAll('.custom-select:not([data-multiple="1"])>.options span');
69
+ for (let i = 0; i < singleSelectOptions.length; i++) {
70
+ singleSelectOptions[i].addEventListener('click', () => {singleSelectClickHandler(singleSelectOptions[i])});
71
+ singleSelectOptions[i].setAttribute('id', 'option-'+i.toString());
72
+ }
73
+
74
+
75
+ /*
76
+ Toggle switch plugin
77
+ Usage example:
78
+ ```
79
+ <input type="hidden" name="searchEng" disabled>
80
+ <div class="searchEng">
81
+ <div class="searchEng-elem">
82
+ <input type="checkbox" id="toggle"/>
83
+ <div data-isCheckbox data-input="searchEng" data-value="ddg">
84
+ <label for="toggle"></label>
85
+ </div>
86
+ <span>Duck duck go</span>
87
+ </div>
88
+ <div class="searchEng-elem">
89
+ <input type="checkbox" id="toggle1"/>
90
+ <div data-isCheckbox data-input="searchEng" data-value="searx">
91
+ <label for="toggle1"></label>
92
+ </div>
93
+ <span>Searx</span>
94
+ </div>
95
+ </div>
96
+ ```
97
+ */
98
+
99
+ document.querySelectorAll('[data-isCheckbox]:not([data-value="all"]) label').forEach(checkBoxLabel => {
100
+ checkBoxLabel.addEventListener('click', () => {
101
+ let checkBox = checkBoxLabel.parentElement;
102
+ let helperInput = checkBox.parentElement.querySelector('input[type="checkbox"]');
103
+ let mainInput = document.getElementsByName(checkBox.getAttribute('data-input'))[0];
104
+ if (helperInput.checked == true) {
105
+ mainInput.value = mainInput.value.replace(checkBox.getAttribute('data-value') + ',', '');
106
+ } else {
107
+ mainInput.value += checkBox.getAttribute('data-value') + ',';
108
+ }
109
+ });
110
+ })
public/templates/header.html CHANGED
@@ -4,9 +4,26 @@
4
  <title>Websurfx</title>
5
  <meta charset="UTF-8" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1" />
7
- <link href="static/colorschemes/{{colorscheme}}.css" rel="stylesheet" type="text/css" />
8
- <link href="static/themes/{{theme}}.css" rel="stylesheet" type="text/css" />
9
  </head>
10
 
11
  <body>
12
  <header>{{>navbar}}</header>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  <title>Websurfx</title>
5
  <meta charset="UTF-8" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <!-- <link href="static/colorschemes/{{colorscheme}}.css" rel="stylesheet" type="text/css" /> -->
8
+ <!-- <link href="static/themes/{{theme}}.css" rel="stylesheet" type="text/css" /> -->
9
  </head>
10
 
11
  <body>
12
  <header>{{>navbar}}</header>
13
+ <script>
14
+ const cookies = document.cookie.split(';').map(item => item.split('=')).
15
+ reduce((acc, [k, v]) => (acc[k.trim().replace('"', '')] = v) && acc, {});
16
+ // Load colorscheme and theme from cookie
17
+ function addCss(fileName) {
18
+ var head = document.head;
19
+ var link = document.createElement("link");
20
+
21
+ link.type = "text/css";
22
+ link.rel = "stylesheet";
23
+ link.href = fileName;
24
+
25
+ head.appendChild(link);
26
+ }
27
+ addCss('static/themes/'+ (cookies["theme"] || '{{theme}}') + '.css');
28
+ addCss('static/colorschemes/'+ (cookies["color-sch"] || '{{colorscheme}}') + '.css');
29
+ </script>
public/templates/navbar.html CHANGED
@@ -1,5 +1,6 @@
1
  <nav>
2
  <ul>
 
3
  <li><a href="about">about</a></li>
4
  <li><a href="settings">settings</a></li>
5
  </ul>
 
1
  <nav>
2
  <ul>
3
+ <li><a href="/">search</a></li>
4
  <li><a href="about">about</a></li>
5
  <li><a href="settings">settings</a></li>
6
  </ul>
public/templates/settings.html CHANGED
@@ -1,5 +1,107 @@
1
  {{>header this}}
2
  <main class="settings">
3
- <h1>Page is under construction</h1>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  </main>
 
 
5
  {{>footer}}
 
1
  {{>header this}}
2
  <main class="settings">
3
+ <h1>Settings</h1>
4
+ <hr>
5
+ <div class="settings-view">
6
+ <div class="settings-sidebar">
7
+ <span class="set-name active" data-detailId="all">All</span>
8
+ <span class="set-name" data-detailId="searchEng">Search Engine</span>
9
+ <span class="set-name" data-detailId="theme">Theme</span>
10
+ </div>
11
+ <div class="settings-detail">
12
+ <form name="settings" onsubmit="submitSettings(); return false;">
13
+ <!-- Search engine settings -->
14
+ <div class="set-item" data-id="searchEng">
15
+ <h3 class="set-name">Select search engines</h3>
16
+ <p class="set-desc">Select the search engines from the list of engines that you want results from</p>
17
+ <!-- toggle element -->
18
+ <input type="hidden" name="searchEng" required value="ddg,searx,">
19
+ <div class="searchEng" takeInput>
20
+ <div class="searchEng-elem">
21
+ <input type="checkbox" id="selectAll-eng" onclick="return selectAllHandler(this);"/>
22
+ <div data-isCheckbox data-input="searchEng" data-value="all">
23
+ <label for="selectAll-eng"></label>
24
+ </div>
25
+ <span>Select all</span>
26
+ </div>
27
+ <hr>
28
+ <div class="searchEng-elem">
29
+ <input type="checkbox" id="toggle" checked/>
30
+ <div data-isCheckbox data-input="searchEng" data-value="ddg">
31
+ <label for="toggle"></label>
32
+ </div>
33
+ <span>Duck duck go</span>
34
+ </div>
35
+ <div class="searchEng-elem">
36
+ <input type="checkbox" id="toggle1" checked/>
37
+ <div data-isCheckbox data-input="searchEng" data-value="searx">
38
+ <label for="toggle1"></label>
39
+ </div>
40
+ <span>Searx</span>
41
+ </div>
42
+ </div>
43
+ <!-- End search select -->
44
+ </div>
45
+ <!-- End search engine setting -->
46
+
47
+ <!-- Theme selection settings -->
48
+ <div class="set-item" data-id="theme">
49
+ <h3 class="set-name">Select theme</h3>
50
+ <p class="set-desc">Select the theme from the available themes to be used in user interface</p>
51
+ <!-- Select element -->
52
+ <input type="hidden" name="theme" style="display: none;" required value="simple"></input>
53
+ <div class="custom-select" tabindex="0" data-input="theme" data-default="simple" takeInput
54
+ data-defaultIfNone="Select">
55
+ <svg viewBox="0 0 24 24" width="2rem" height="2rem" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
56
+ <path d="M6.1018 8C5.02785 8 4.45387 9.2649 5.16108 10.0731L10.6829 16.3838C11.3801 17.1806 12.6197 17.1806
57
+ 13.3169 16.3838L18.8388 10.0731C19.5459 9.2649 18.972 8 17.898 8H6.1018Z">
58
+ </path>
59
+ </svg>
60
+ <div class="options">
61
+ <span data-value="simple" selected>simple</span>
62
+ </div>
63
+ </div>
64
+ <!-- End select element -->
65
+ </div>
66
+ <!-- End theme selection select -->
67
+
68
+ <!-- Color scheme selection settings -->
69
+ <div class="set-item" data-id="theme">
70
+ <h3 class="set-name">Select Color Scheme</h3>
71
+ <p class="set-desc">Select the color scheme for your theme to be used in user interface</p>
72
+ <!-- Select element -->
73
+ <input type="hidden" name="color-sch" style="display: none;" required value="catppuccin-mocha"></input>
74
+ <div class="custom-select" tabindex="0" data-input="color-sch" data-default="catppuccin-mocha" takeInput
75
+ data-defaultIfNone="Select">
76
+ <svg viewBox="0 0 24 24" width="2rem" height="2rem" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
77
+ <path d="M6.1018 8C5.02785 8 4.45387 9.2649 5.16108 10.0731L10.6829 16.3838C11.3801 17.1806 12.6197 17.1806
78
+ 13.3169 16.3838L18.8388 10.0731C19.5459 9.2649 18.972 8 17.898 8H6.1018Z">
79
+ </path>
80
+ </svg>
81
+ <div class="options">
82
+ <span data-value="catppuccin-mocha" selected>catppuccin-mocha</span>
83
+ <span data-value="dracula">dracula</span>
84
+ <span data-value="monokai">monokai</span>
85
+ <span data-value="nord">nord</span>
86
+ <span data-value="oceanic-next">oceanic-next</span>
87
+ <span data-value="solarized-dark">solarized-dark</span>
88
+ <span data-value="solarized-light">solarized-light</span>
89
+ <span data-value="tomorrow-night">tomorrow-night</span>
90
+ </div>
91
+ </div>
92
+ <!-- End select element -->
93
+ </div>
94
+ <!-- End color scheme selection -->
95
+
96
+ <!-- ACTIONS -->
97
+ <div class="actions">
98
+ <input type="submit" value="Submit" class="submit-btn">
99
+ </div>
100
+ <!-- End Actions -->
101
+ </form>
102
+ </div>
103
+ </div>
104
  </main>
105
+ <script src="static/ui_plugins.js"></script>
106
+ <script src="static/settings.js"></script>
107
  {{>footer}}