@nebularstreams/libmui 2.0.14 → 2.0.15

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nebularstreams/libmui",
3
3
  "description": "Micro UI based on Mithril",
4
- "version": "2.0.14",
4
+ "version": "2.0.15",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
7
7
  "scripts": {
package/src/index.js CHANGED
@@ -21,8 +21,11 @@ import SmileysButton from "./widgets/SmileysButton";
21
21
  import startApp from "./app/app"
22
22
  import defineWidget from "./util/widgets.utils";
23
23
  import {OverflowMenu} from "./util/widgets.core";
24
- import {confirm, confirmPromise} from "./util/fuckingconfirm.js"
25
-
24
+ import {confirm, confirmPromise} from "./util/fuckingconfirm"
25
+ import clone from "./util/util.clone"
26
+ import Tokenizer from "./util/util.tokenizer"
27
+ import {CoolContentTicker, CoolGenericTicker, GenericButtonTicker, optionsPrompt} from "./widgets/CoolContentTicker";
28
+ import EmptyButton from "./widgets/EmptyButton";
26
29
 
27
30
  import {
28
31
  VideoUploadButton,
@@ -45,10 +48,11 @@ export {
45
48
  ButtonChoiceWidget,
46
49
  ButtonNew,
47
50
  CardieWidget,
51
+ ColorJoeWidget,
48
52
  ComboPrompt,
49
53
  ComboWidget,
50
- ColorJoeWidget,
51
54
  Empty,
55
+ EmptyButton,
52
56
  Icon,
53
57
  InputWidget,
54
58
  NoticeWidget,
@@ -79,7 +83,15 @@ export {
79
83
  MultiToggleWidget,
80
84
  RangeToggleWidget,
81
85
 
86
+ // Content Ticker
87
+ CoolContentTicker,
88
+ CoolGenericTicker,
89
+ GenericButtonTicker,
90
+ optionsPrompt,
91
+ Tokenizer,
92
+
82
93
  clearModal,
94
+ clone,
83
95
  confirm,
84
96
  confirmPromise,
85
97
  defineWidget,
@@ -215,12 +215,38 @@ function tokenizeUrl(tokenizedUrl, parameters, options) {
215
215
  return message || "(not enough parameters)";
216
216
  }
217
217
  }
218
+
218
219
  function sanitizeFilename(filename) {
219
220
  return filename ? filename.trim()
220
221
  .toLowerCase()
221
222
  .replace(/[^0-9A-Z.-]+/gi, "") : null;
222
223
  }
223
224
 
225
+
226
+ const generateFilename = (url, prefix = undefined) => {
227
+
228
+ const
229
+ dateCode = parseInt(md5(url)
230
+ .substring(24), 16)
231
+ .toString(32);
232
+
233
+ return (prefix ? sanitizeFilename(prefix) + "-" : "") + dateCode;
234
+
235
+ }; // 2025 --- 24 years layer i'm 50 ! I wonder about my past self ...
236
+
237
+ const Tokenizer = {
238
+ tokenize,
239
+ tokenizeStrict,
240
+ tokenizeObject,
241
+ tokenizeKeep,
242
+ tokenizeWithDefault,
243
+ tokenizeUrl,
244
+ getPointedData,
245
+ sanitizeFilename,
246
+ generateFilename
247
+ };
248
+
249
+ export default Tokenizer;
224
250
  export {
225
251
  tokenize,
226
252
  tokenizeStrict,
@@ -229,5 +255,6 @@ export {
229
255
  tokenizeWithDefault,
230
256
  tokenizeUrl,
231
257
  getPointedData,
232
- sanitizeFilename
258
+ sanitizeFilename,
259
+ generateFilename
233
260
  };
@@ -0,0 +1,239 @@
1
+ import {defineWidget, ButtonNew} from "./Basic.js"
2
+ import {promptName} from "./OverflowUtils"
3
+ import {confirmPromise} from "../util/fuckingconfirm"
4
+
5
+ const
6
+ ThematicWrapper = defineWidget(
7
+ ({attrs, children}) => m(
8
+ ".buttonchoice.withicon.flexrow.scaff.scaff-b1.fadein.ohidden.fa-" + (attrs.icon || "gear"),
9
+ {class: (attrs.containerClass || "col-11 grows marg-1"), title: attrs.title},
10
+ m(
11
+ ".flexrow.wrap.grows.col-11.ohidden.scaff-left.bg-inputs",
12
+ {class: attrs.class},
13
+ children
14
+ )
15
+ )
16
+ ),
17
+ optionsPrompt = (items, index, onAdd, onDelete, onEdit, allowUpdate) => {
18
+
19
+ const item = items[index];
20
+
21
+ confirmPromise(
22
+ null,
23
+
24
+ "Choose an action for this preset",
25
+
26
+ onAdd && allowUpdate
27
+ ? ["DELETE", "RENAME", "UPDATE", "CANCEL"]
28
+ : ["DELETE", "RENAME", "CANCEL"]
29
+ )
30
+ .then(({idx}) => {
31
+
32
+ if (idx === 0) {
33
+ items.splice(index, 1);
34
+ if (onDelete) onDelete(index);
35
+ m.redraw();
36
+ } else if (idx === 1) {
37
+ setTimeout(() => promptName(
38
+ "Rename Preset",
39
+ item.title || "",
40
+ "type a name for this preset",
41
+ (newName) => {
42
+ if (newName) {
43
+ newName = newName.trim();
44
+ if (newName) {
45
+ item.title = newName.substring(0, 24);
46
+ m.redraw();
47
+ }
48
+ }
49
+ }
50
+ ), 10);
51
+ } else if (onAdd && idx === 2) {
52
+ onAdd(false, index);
53
+ }
54
+ });
55
+ },
56
+ GenericButtonTicker = defineWidget(
57
+ ({attrs, children}) => {
58
+
59
+ const
60
+ {
61
+ title, noUpdate, items = [], current, altIndex, onEdit, emptyText,
62
+ onAdd, onSelect, onDelete, addText = "Add New",
63
+ unconfirm, buttonClass, themeIcon, themeTitle
64
+ } = attrs,
65
+
66
+ allItems = [
67
+
68
+ ...items.map(
69
+ (item, index) => m(
70
+ "button.grows.marg-1.ellipsis.ohidden.hasShift",
71
+ {
72
+
73
+ class: (buttonClass ? buttonClass : "unitheightsmall scaff-b1")
74
+ + (index === current ? " accent" : "")
75
+ + (index === altIndex ? " alt-accent" : ""),
76
+
77
+ title,
78
+ onclick: (e) => {
79
+ if (e.metaKey && onEdit) {
80
+ onEdit(item);
81
+ } else if (onAdd && e.shiftKey) {
82
+ if (unconfirm) {
83
+ items.splice(index, 1);
84
+ if (onDelete) onDelete(index);
85
+ m.redraw();
86
+ } else {
87
+ optionsPrompt(items, index, onAdd, onDelete, undefined, !noUpdate);
88
+ }
89
+ } else {
90
+ onSelect(item, index, e.metaKey, e.shiftKey);
91
+ }
92
+ }
93
+ },
94
+ (item.title || item.name || item.text || String(1 + index)).substring(0, 32)
95
+ )
96
+ ),
97
+
98
+ ...!items.length && emptyText
99
+ ? [
100
+ m(".grows.marg-1.ellipsis.ohidden.al-center", emptyText)
101
+ ] : [],
102
+
103
+ ...onAdd
104
+ ? [
105
+ m(ButtonNew, {
106
+ tabIndex: -1,
107
+ icon: attrs.icon || "plus",
108
+ title: attrs.addTitle || "Add a new item",
109
+ class: "pad-2 pad-h al-center unitheightsmall transp addbut scaff-left bg-window-lo grows",
110
+ onClick: (e) => onAdd(e.ctrlKey || e.metaKey),
111
+ text: items?.length ? "" : addText
112
+ })
113
+ ]
114
+ : [],
115
+
116
+ ...!themeIcon && attrs.currentWidget && current >= 0 && items[current]
117
+ ? attrs.currentWidget(items[current], current) || []
118
+ : [],
119
+
120
+ ...children
121
+ ];
122
+
123
+ return themeIcon
124
+ ? [
125
+ m(ThematicWrapper, {
126
+ title: themeTitle,
127
+ containerClass: attrs.containerClass,
128
+ icon: themeIcon
129
+ }, allItems),
130
+ ...attrs.currentWidget && current >= 0 && items[current] ? attrs.currentWidget(items[current], current) || [] : []
131
+ ] : allItems;
132
+ }
133
+ ),
134
+ CoolGenericTicker = defineWidget(
135
+ ({attrs, children}) => {
136
+
137
+ const
138
+ {
139
+ nocontainer,
140
+ emptyText,
141
+ title,
142
+ addTitle,
143
+ items,
144
+ currentIndex,
145
+ altIndex,
146
+ onEdit,
147
+ onDelta,
148
+ onSelect,
149
+ onAdd,
150
+ addText,
151
+ icon,
152
+ buttonClass
153
+ } = attrs,
154
+ itemz = ((items && items.length <= (attrs.max || 15)) || !onDelta)
155
+ ? m(GenericButtonTicker, {
156
+ addTitle,
157
+ emptyText,
158
+ title,
159
+ items,
160
+ current: currentIndex,
161
+ altIndex,
162
+ onSelect,
163
+ onAdd,
164
+ onEdit,
165
+ addText,
166
+ icon,
167
+ buttonClass
168
+ }, children)
169
+ : [
170
+ m(ButtonNew, {
171
+ tabIndex: -1,
172
+ icon: "caret-right",
173
+ class: "unitheightsmall grows marg-1 no-marg-left",
174
+ onClick: () => onDelta(-1)
175
+ }),
176
+ ...items
177
+ ? [
178
+ m(
179
+ ".scaff.unitheightsmall.value.al-center.bg-window-lo.grows.marg-1.no-marg-left ",
180
+ (1 + currentIndex) + " / " + items.length
181
+ )
182
+ ]
183
+ : [],
184
+ m(ButtonNew, {
185
+ tabIndex: -1,
186
+ icon: "caret-left",
187
+ class: "unitheightsmall grows marg-1 marg-v",
188
+ onClick: () => onDelta(1)
189
+ }),
190
+ ...onAdd
191
+ ? [
192
+ m(ButtonNew, {
193
+ tabIndex: -1,
194
+ icon: attrs.icon || "plus",
195
+ class: "unitheightsmall marg-1 marg-v",
196
+ onClick: () => onAdd()
197
+ })
198
+ ] : []
199
+ ];
200
+
201
+ return nocontainer
202
+ ? itemz
203
+ : items.length || !onAdd ? m(
204
+ ".flexrow.wrap.max.minusbar",
205
+ {class: (attrs.dynclass ? attrs.dynclass() + " " : "") + attrs.class},
206
+ itemz
207
+ ) : [];
208
+ }
209
+ ),
210
+
211
+ CoolContentTicker = defineWidget(
212
+ ({attrs}) => {
213
+
214
+ if (!attrs.layer.items) return [];
215
+
216
+ const
217
+ {global, layer, remoteFirst: isRemote, isCue} = attrs,
218
+ {storyWrapper} = global,
219
+ {id, items} = layer,
220
+
221
+ currentIndex = storyWrapper.getTickerIndex(id, isRemote),
222
+ altIndex = isRemote ? storyWrapper.getTickerIndex(id, false) : undefined;
223
+
224
+ // noinspection JSUnusedGlobalSymbols
225
+ return m(CoolGenericTicker, {
226
+ title: attrs.title,
227
+ onAdd: attrs.onAdd,
228
+ class: "marg-1 marg-h grows",
229
+ items,
230
+ currentIndex,
231
+ altIndex,
232
+ current: items[currentIndex] || undefined,
233
+ onDelta: (direction) => storyWrapper.tickLayer(layer, direction, isRemote, isCue),
234
+ onSelect: (item, index, force) => storyWrapper.setTickerIndex(layer, index, force, isRemote, isCue)
235
+ });
236
+ }
237
+ );
238
+
239
+ export {CoolContentTicker, CoolGenericTicker, GenericButtonTicker, optionsPrompt};
@@ -0,0 +1,39 @@
1
+ const
2
+
3
+ m = require("mithril"),
4
+ defineWidget = require("util.definewidget"),
5
+
6
+ { ButtonNew, Empty } = require("app.widgets");
7
+
8
+ const EmptyButton = defineWidget(
9
+ ({ attrs }) => m(
10
+ Empty,
11
+ {
12
+ size: 2,
13
+ icon: attrs.icon,
14
+ class: "pad-2"
15
+ },
16
+ [
17
+ ...attrs.texts
18
+ .map((text) => m(".text", text)),
19
+ ...attrs.buttonText ? [
20
+ m(ButtonNew, {
21
+ class: "font-125 accentbutton unitheightsmall",
22
+ icon: attrs.icon || "plus",
23
+ text: attrs.buttonText,
24
+ onClick: attrs.onClick
25
+ })
26
+ ] : [],
27
+ ...attrs.buttonAlt ? [
28
+ m(ButtonNew, {
29
+ class: "font-125 accentbutton unitheightsmall",
30
+ icon: attrs.iconAlt || "plus",
31
+ text: attrs.buttonTextAlt,
32
+ onClick: attrs.onClick
33
+ })
34
+ ] : []
35
+ ]
36
+ )
37
+ );
38
+
39
+ module.exports = EmptyButton;