Skip to content

Commit 1c32058

Browse files
Syntax lookup: use reducer and correctly link URL state with internal state
1 parent 78046ea commit 1c32058

8 files changed

+209
-151
lines changed

bsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
},
77
"bs-dependencies": [
88
"@rescript/react",
9-
"@ryyppy/rescript-promise"
9+
"@ryyppy/rescript-promise",
10+
"rescript-react-update"
1011
],
1112
"ppx-flags": [],
1213
"sources": [

package-lock.json

+17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"remark-slug": "^5.1.2",
3030
"remark-stringify": "^7.0.3",
3131
"request": "^2.88.0",
32+
"rescript-react-update": "^4.0.0",
3233
"stringify-object": "^3.3.0",
3334
"unified": "^8.4.0"
3435
},

src/SyntaxLookup.mjs

+120-84
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import * as SearchBox from "./components/SearchBox.mjs";
1010
import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
1111
import * as Belt_Option from "rescript/lib/es6/belt_Option.js";
1212
import * as Caml_option from "rescript/lib/es6/caml_option.js";
13+
import * as ReactUpdate from "rescript-react-update/src/ReactUpdate.mjs";
1314
import * as GithubSlugger from "github-slugger";
1415

1516
var indexData = (require('index_data/syntax_index.json'));
@@ -146,88 +147,118 @@ function SyntaxLookup$DetailBox(Props) {
146147
}, children));
147148
}
148149

150+
function stateFromPath(path) {
151+
return Belt_Option.getWithDefault(Belt_Option.map(Belt_Option.flatMap(getAnchor(path), (function (anchor) {
152+
return Caml_option.undefined_to_opt(allItems.find(function (item) {
153+
return GithubSlugger.slug(item.id) === anchor;
154+
}));
155+
})), (function (item) {
156+
return {
157+
TAG: 1,
158+
_0: item,
159+
[Symbol.for("name")]: "ShowDetails"
160+
};
161+
})), /* ShowAll */0);
162+
}
163+
149164
function SyntaxLookup(Props) {
150165
var router = Next.Router.useRouter(undefined);
151-
var match = React.useState(function () {
152-
return /* ShowAll */0;
153-
});
154-
var setState = match[1];
155-
var state = match[0];
156-
React.useEffect((function () {
157-
var anchor = getAnchor(router.asPath);
158-
if (anchor !== undefined) {
159-
Belt_Option.forEach(Caml_option.undefined_to_opt(allItems.find(function (item) {
160-
return GithubSlugger.slug(item.id) === anchor;
161-
})), (function (item) {
162-
return Curry._1(setState, (function (param) {
163-
return {
164-
TAG: 1,
165-
_0: item,
166-
[Symbol.for("name")]: "ShowDetails"
167-
};
168-
}));
169-
}));
170-
}
171-
172-
}), []);
173-
React.useEffect((function () {
174-
var match = getAnchor(router.asPath);
175-
var exit = 0;
176-
if (typeof state === "number" || state.TAG === /* ShowFiltered */0) {
177-
exit = 1;
178-
} else {
179-
var item = state._0;
180-
if (match !== undefined) {
181-
var slug = GithubSlugger.slug(item.id);
182-
if (slug !== match) {
183-
Next.Router.push(router, "syntax-lookup#" + match);
184-
}
185-
186-
} else {
187-
Next.Router.push(router, "syntax-lookup#" + GithubSlugger.slug(item.id));
188-
}
189-
}
190-
if (exit === 1) {
191-
if (match !== undefined) {
192-
Next.Router.push(router, "syntax-lookup");
193-
}
194-
195-
}
196-
197-
}), [state]);
198-
var onSearchValueChange = function (value) {
199-
return Curry._1(setState, (function (param) {
200-
if (value === "") {
201-
return /* ShowAll */0;
202-
}
203-
var filtered = Belt_Array.map(fuse.search(value), (function (m) {
204-
return m.item;
205-
}));
206-
if (filtered.length !== 1) {
207-
return {
166+
var match = ReactUpdate.useReducerWithMapState((function (_state, action) {
167+
switch (action.TAG | 0) {
168+
case /* URLChanged */0 :
169+
return {
170+
TAG: 0,
171+
_0: stateFromPath(action._0),
172+
[Symbol.for("name")]: "Update"
173+
};
174+
case /* SearchValueChanged */1 :
175+
var search = action._0;
176+
if (search === "") {
177+
return {
178+
TAG: 1,
179+
_0: /* ShowAll */0,
180+
_1: (function (param) {
181+
Next.Router.push(router, "syntax-lookup");
182+
183+
}),
184+
[Symbol.for("name")]: "UpdateWithSideEffects"
185+
};
186+
}
187+
var filtered = Belt_Array.map(fuse.search(search), (function (m) {
188+
return m.item;
189+
}));
190+
if (filtered.length !== 1) {
191+
return {
192+
TAG: 0,
193+
_0: {
208194
TAG: 0,
209-
_0: value,
195+
_0: search,
210196
_1: filtered,
211197
[Symbol.for("name")]: "ShowFiltered"
212-
};
213-
}
214-
var item = Belt_Array.getExn(filtered, 0);
215-
if (item.name === value) {
216-
return {
198+
},
199+
[Symbol.for("name")]: "Update"
200+
};
201+
}
202+
var item = filtered[0];
203+
if (item.name === search) {
204+
return {
205+
TAG: 1,
206+
_0: {
217207
TAG: 1,
218208
_0: item,
219209
[Symbol.for("name")]: "ShowDetails"
220-
};
221-
} else {
222-
return {
210+
},
211+
_1: (function (param) {
212+
Next.Router.push(router, "syntax-lookup#" + GithubSlugger.slug(item.id));
213+
214+
}),
215+
[Symbol.for("name")]: "UpdateWithSideEffects"
216+
};
217+
} else {
218+
return {
219+
TAG: 0,
220+
_0: {
223221
TAG: 0,
224-
_0: value,
222+
_0: search,
225223
_1: filtered,
226224
[Symbol.for("name")]: "ShowFiltered"
227-
};
228-
}
225+
},
226+
[Symbol.for("name")]: "Update"
227+
};
228+
}
229+
case /* ItemSelected */2 :
230+
var item$1 = action._0;
231+
return {
232+
TAG: 1,
233+
_0: {
234+
TAG: 1,
235+
_0: item$1,
236+
[Symbol.for("name")]: "ShowDetails"
237+
},
238+
_1: (function (param) {
239+
Next.Router.push(router, "syntax-lookup#" + GithubSlugger.slug(item$1.id));
240+
241+
}),
242+
[Symbol.for("name")]: "UpdateWithSideEffects"
243+
};
244+
245+
}
246+
}), (function (param) {
247+
return stateFromPath(router.asPath);
248+
}));
249+
var dispatch = match[1];
250+
var state = match[0];
251+
React.useEffect((function () {
252+
Next.Router.beforePopState(router, (function (param) {
253+
Curry._1(dispatch, {
254+
TAG: 0,
255+
_0: param.url,
256+
[Symbol.for("name")]: "URLChanged"
257+
});
258+
return true;
229259
}));
230-
};
260+
261+
}), []);
231262
var details;
232263
if (typeof state === "number" || state.TAG === /* ShowFiltered */0) {
233264
details = null;
@@ -272,13 +303,11 @@ function SyntaxLookup(Props) {
272303
var children = Belt_Array.map(items, (function (item) {
273304
var onMouseDown = function (evt) {
274305
evt.preventDefault();
275-
return Curry._1(setState, (function (param) {
276-
return {
277-
TAG: 1,
278-
_0: item,
279-
[Symbol.for("name")]: "ShowDetails"
280-
};
281-
}));
306+
return Curry._1(dispatch, {
307+
TAG: 2,
308+
_0: item,
309+
[Symbol.for("name")]: "ItemSelected"
310+
});
282311
};
283312
return React.createElement("span", {
284313
key: item.name,
@@ -316,11 +345,6 @@ function SyntaxLookup(Props) {
316345
[item$1]
317346
];
318347
}
319-
var onSearchClear = function (param) {
320-
return Curry._1(setState, (function (param) {
321-
return /* ShowAll */0;
322-
}));
323-
};
324348
return React.createElement("div", undefined, React.createElement("div", {
325349
className: "flex flex-col items-center"
326350
}, React.createElement("div", {
@@ -342,9 +366,21 @@ function SyntaxLookup(Props) {
342366
return item.name;
343367
})),
344368
value: match$1[0],
345-
onClear: onSearchClear,
369+
onClear: (function (param) {
370+
return Curry._1(dispatch, {
371+
TAG: 1,
372+
_0: "",
373+
[Symbol.for("name")]: "SearchValueChanged"
374+
});
375+
}),
346376
placeholder: "Enter keywords or syntax...",
347-
onValueChange: onSearchValueChange
377+
onValueChange: (function (value) {
378+
return Curry._1(dispatch, {
379+
TAG: 1,
380+
_0: value,
381+
[Symbol.for("name")]: "SearchValueChanged"
382+
});
383+
})
348384
}))), React.createElement("div", {
349385
className: "mt-10"
350386
}, details, categories));

0 commit comments

Comments
 (0)