Nice little directory browser :D
1@*
2 This file is part of Utatane.
3
4 Utatane is free software: you can redistribute it and/or modify it under
5 the terms of the GNU Affero General Public License as published by the Free
6 Software Foundation, either version 3 of the License, or (at your option)
7 any later version.
8
9 Utatane is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
12 more details.
13
14 You should have received a copy of the GNU Affero General Public License
15 along with Utatane. If not, see <http://www.gnu.org/licenses/>.
16*@
17
18<header class="n-box">
19 <Breadcrumbs Path="@Path" />
20 <div id="toolbar">
21 <button id="reload-table"
22 class="clickable"
23 type="button"
24 aria-label="Reload table"
25 _="
26-- shortcut: only the active <th> will have aria-sort
27on click send nhnd:run to <th[aria-sort]/>
28"
29 >
30 <span class="[vertical-align:sub]">↻</span>
31 </button>
32
33 <GoBackButton Path="@Path"/>
34
35 <abbr id="search-label" title="Search">🔎</abbr>
36 <input id="search" class="border-black" type="search" aria-labelledby="search-label" _="@_scriptForIdSearch" />
37
38 <abbr id="rx-label" title="Search with RegEx">.*</abbr>
39 <input id="use-rx-for-search" type="checkbox" autocomplete="off" aria-labelledby="rx-label" _="@_scriptForIdUseRxForSearch" />
40
41 <abbr id="case-label" title="Case sensitive search">Aa</abbr>
42 <input id="use-case-for-search" type="checkbox" autocomplete="off" aria-labelledby="case-label" />
43
44 <span id="file-counter" class="my-auto" _="@_scriptForIdFileCounter" />
45 </div>
46 <hr/>
47 <ThankYouTestUser />
48</header>
49
50@code {
51
52 [Parameter]
53 public required String Path { get; set; }
54
55 #region _hyperscript strings
56 // these are just the big ones, smaller ones are littered throughout
57 private readonly String _scriptForIdSearch = @"
58on load
59 set my value to ''
60on input
61 js(me)
62 let jme = $(me);
63 let rxSearch = null;
64 try {
65 rxSearch = new RegExp(jme.val(), $('#use-case-for-search').prop('checked') ? '' : 'i');
66 } catch (e) {
67 return null;
68 }
69 let rows = $('tbody > tr');
70 rows.addClass('hidden');
71 rows
72 .filter((i, el) => rxSearch.test(
73 $('.file-name', el).attr('data-order')
74 ))
75 .removeClass('hidden');
76 end
77 send nhnd:update to #file-counter
78on keydown[key==""Enter""]
79 js(me, event)
80 if (event.isComposing || event.keyCode === 228) {
81 return
82 } else {
83 $('#filetable-body > tr:not(.hidden) > .file-name > a').first().dispatchEvent(newEvent('click'))
84 $(me).val('')
85 }
86 end
87on keydown from body
88 js(me, event)
89 let rx = new RegExp(""^(F|Soft)\d"");
90 return (!(
91 document.activeElement === me // dont repeat it!
92 || event.key == """" // (actually I forgot)
93 || event.ctrlKey || event.altKey || event.metaKey // dont react on modifier combos
94 || [""Shift"", ""Tab"", ""ArrowUp"", ""ArrowRight"", ""ArrowLeft"", ""ArrowDown"",
95 ""AltGraph"", ""CapsLock"", ""Fn"", ""FnLock"", ""Hyper"", ""NumLock"",
96 ""ScrollLock"", ""Super"", ""Symbol"", ""SymbolLock"", ""OS"", ""End"", ""Home"",
97 ""PageDown"", ""PageUp"", ""Backspace"", ""Clear"", ""Delete"", ""Redo"",
98 ""Undo"", ""Accept"", ""Again"", ""Attn"", ""Cancel"", ""ContextMenu"",
99 ""Escape"", ""Find"", ""Pause"", ""Play"", ""Props"", ""Select"", ""ZoomIn"",
100 ""ZoomOut"", ""Apps"", ""BrightnessDown"", ""BrightnessUp"", ""PrintScreen"",
101 ""MediaFastForward"", ""MediaPause"", ""MediaPlay"", ""MediaPlayPause"",
102 ""MediaRecord"", ""MediaRewind"", ""MediaStop"", ""MediaTrackNext"",
103 ""MediaTrackPrevious""
104 ].includes(event.key) // special keys to not react on
105 || rx.test(event.key) // more special keys but these can be regexed
106 ))
107 end
108
109 if it is true then
110 focus() on me
111 go to the top of the body smoothly
112";
113
114 private readonly String _scriptForIdUseRxForSearch = @"
115on load or click -- on load for if this comes checked
116 js
117 $('#search')
118 [ $('#use-rx-for-search').prop('checked') ? 'addClass' : 'removeClass' ]('font-mono')
119 .dispatchEvent(newEvent('input'))
120 end
121";
122
123 private readonly String _scriptForIdFileCounter = @"
124on nhnd:update
125 set files to $('.file:not(.hidden)').length
126 set dirs to $('.directory:not(.hidden)').length
127 set my innerHTML to `${dirs} __W ${files} __X`
128"
129 .Replace("__W", Utils.AbbrIconPlain("Directories", "📁"))
130 .Replace("__X", Utils.AbbrIconPlain("Files", "📄"));
131
132 #endregion _hyperscript strings
133
134}