Skip to content

Instantly share code, notes, and snippets.

View librz's full-sized avatar

Patrick Ren librz

View GitHub Profile
@librz
librz / getErrorMessage.tsx
Created June 22, 2024 09:31
Get error message when an error is thrown
export function getErrorMessage(err: unknown, defaultMessage = "An error occurred") {
if (err instanceof Error && err.message) {
return err.message;
}
if (err instanceof Object && "message" in err && typeof err.message === "string" && err.message) {
return err.message;
}
if (typeof err === "string" && err) {
return err;
}
@librz
librz / index.md
Created April 16, 2024 11:51
`as const` except in js

In TypeScript, u can easily declare constants using as const:

const Meal = {
  Breakfast: 'breakfast',
  Lunch: 'lunch',
  Dinner: 'dinner'
}
@librz
librz / form-use-blocker.tsx
Last active April 11, 2024 12:43
React Router V6, Demo of prompt user for confirm when user navigate away or reload/close the page
import { useState } from "react";
import { useBeforeUnload, useBlocker } from "react-router-dom";
// unstable_usePrompt: https://reactrouter.com/en/main/hooks/use-prompt
// useBlocker: https://reactrouter.com/en/main/hooks/use-blocker
// useBeforeUnload: https://reactrouter.com/en/main/hooks/use-before-unload
export default function Form() {
const [input, setInput] = useState("");
@librz
librz / use-search-params.ts
Last active March 25, 2024 08:31
解决 react-router-dom v5 没有 useSearchParams 的问题
/**
* 以下代码来自 react-router-dom v6,用于解决 react-router-dom v5 没有 useSearchParams 的问题
* see: https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/index.tsx#L1432
* 在原代码的基础上做的改动:
* 1. 原代码使用了 useNavigate,但 react-router v5 还没有这个 hook,使用 useHistory 代替(https://reactrouter.com/en/main/upgrading/v5#use-usenavigate-instead-of-usehistory)
* 2. 在返回的数组中提供 updateSearchParams 以在保留其他参数的情况下设置/更新指定的参数
*/
import React, { useCallback } from 'react';
import { useLocation, useHistory } from 'react-router';
@librz
librz / groupByKeys.js
Created January 29, 2024 19:13
用 object 的 key 对 array of objects 进行分组
const list = [
{ province: '天津', city: '南开', district: '三马路' },
{
province: '天津',
city: '南开',
district: '四马路'
},
{
province: '天津',
city: '河西',
@librz
librz / crawl_menu_urls.js
Last active October 8, 2023 09:10
Example of crawling 2-level deep menus & asynchronously get their URLs
/*
note: this is not a general purpose crawling script & can be only used as a reference
background:
1. target site has a side bar which contains many level-1 menus, each level-1 menu contains many level-2 menus
2. level-1 menu stores category name; level-2 menu stores system name, upon click will fire related event & load content as an iframe
*/
const sideMenu = document.querySelector("#side-menu");
const menus = Array.from(sideMenu.querySelectorAll(":scope > li:has(> ul.mm-collapse)"));
@librz
librz / rename_files.js
Last active September 8, 2023 20:19
Batch rename files (using regex with capture group)
// this script does not handle file suffix for you
// as some files have multiple suffix segments, e.g: *.sc.ass & *.tc.ass are two common subtitle formats
// instead, you should manually specify suffix in regex as the last capture group
const fs = require("fs")
const isDryrun = !process.argv.includes("-r");
if (isDryrun) {
console.log("Note: By default, this script will only dry run, specify -r if you want to actually run it.")
@librz
librz / NotFound.html
Last active August 17, 2023 01:41
404 page using tailwind
<section className="h-full w-full flex justify-center items-center gap-8 p-6 flex-col md:flex-row">
<div className="rounded-full w-36 h-36 bg-black font-semibold flex justify-center items-center text-6xl text-white">
404
</div>
<div className="flex flex-col items-end">
<div className="text-5xl">Oops</div>
<div className="text-2xl mt-2 mb-6 text-end">This page doesn't exist</div>
<span className="bg-black text-white px-4 py-2 rounded-md cursor-pointer">
Home
</span>
@librz
librz / ErrorFallback.tsx
Created August 15, 2023 20:48
React Error Fallback Component
import { FallbackProps } from "react-error-boundary";
import React, { CSSProperties } from "react";
const ErrorFallback: React.ComponentType<FallbackProps> = ({
error,
resetErrorBoundary,
}) => {
const sectionStyle: CSSProperties = {
display: "flex",
flexDirection: "column",
@librz
librz / prevent_dev_tools.js
Created August 4, 2023 21:29
Evil hack that prevents user from inspecting web page
function check() {
const minimalUserResponseInMiliseconds = 200;
console.clear();
let before = new Date().getTime();
debugger;
let after = new Date().getTime();
if (after - before > minimalUserResponseInMiliseconds) {
document.write(" Don't open Developer Tools.");
window.location.reload();
}