139 lines
2.9 KiB
TypeScript
139 lines
2.9 KiB
TypeScript
import { type Accessor } from "solid-js";
|
|
|
|
import { useLocation } from "@solidjs/router";
|
|
|
|
/**
|
|
* We re-export everything to prevent us importing @solidjs/router
|
|
* more than once in the project, this can cause some weird behaviour
|
|
* where it can't find the context. This is a side-effect of working
|
|
* in a monorepo. Ideally, this should be done any time we import
|
|
* a new library that is used in multiple components.
|
|
*/
|
|
export {
|
|
Navigate,
|
|
Route,
|
|
Router,
|
|
useBeforeLeave,
|
|
useLocation,
|
|
useNavigate,
|
|
useParams,
|
|
} from "@solidjs/router";
|
|
|
|
const RE_SERVER = /\/server\/([A-Z0-9]{26})/;
|
|
const RE_CHANNEL = /\/channel\/([A-Z0-9]{26})/;
|
|
const RE_MESSAGE_ID = /\/channel\/[A-Z0-9]{26}\/([A-Z0-9]{26})/;
|
|
const RE_BOT_ID = /\/bot\/([A-Z0-9]{26})/;
|
|
|
|
const RE_INVITE_EXACT = /^\/invite\/([\w\d]+)$/;
|
|
const RE_BOT_ID_EXACT = /^\/bot\/[A-Z0-9]{26}$/;
|
|
|
|
const RE_SERVER_EXACT = /^\/server\/([A-Z0-9]{26})$/;
|
|
const RE_CHANNEL_EXACT =
|
|
/^(?:\/server\/[A-Z0-9]{26})?\/channel\/([A-Z0-9]{26})(?:\/[A-Z0-9]{26})?$/;
|
|
const RE_MESSAGE_ID_EXACT =
|
|
/^(?:\/server\/[A-Z0-9]{26})?\/channel\/[A-Z0-9]{26}\/([A-Z0-9]{26})$/;
|
|
|
|
/**
|
|
* Route parameters available globally
|
|
*/
|
|
type GlobalParams = {
|
|
/**
|
|
* Invite ID
|
|
*/
|
|
inviteId?: string;
|
|
|
|
/**
|
|
* Server ID
|
|
*/
|
|
serverId?: string;
|
|
|
|
/**
|
|
* Exact match for server?
|
|
*/
|
|
exactServer: boolean;
|
|
|
|
/**
|
|
* Channel ID
|
|
*/
|
|
channelId?: string;
|
|
|
|
/**
|
|
* Exact match for channel?
|
|
*/
|
|
exactChannel: boolean;
|
|
|
|
/**
|
|
* Message ID
|
|
*/
|
|
messageId?: string;
|
|
|
|
/**
|
|
* Exact match for message?
|
|
*/
|
|
exactMessage: boolean;
|
|
|
|
/**
|
|
* Bot ID
|
|
*/
|
|
botId?: string;
|
|
|
|
/**
|
|
* Exact match for bot?
|
|
*/
|
|
exactBot: boolean;
|
|
};
|
|
|
|
/**
|
|
* Generate global params from path
|
|
* @param pathname Path
|
|
* @returns Params
|
|
*/
|
|
export function paramsFromPathname(pathname: string): GlobalParams {
|
|
const params: GlobalParams = {
|
|
exactServer: !!pathname.match(RE_SERVER_EXACT),
|
|
exactChannel: !!pathname.match(RE_CHANNEL_EXACT),
|
|
exactMessage: !!pathname.match(RE_MESSAGE_ID_EXACT),
|
|
exactBot: !!pathname.match(RE_BOT_ID_EXACT),
|
|
};
|
|
|
|
// Check for invite ID
|
|
const invite = pathname.match(RE_INVITE_EXACT);
|
|
if (invite) {
|
|
params.inviteId = invite[1];
|
|
}
|
|
|
|
// Check for server ID
|
|
const server = pathname.match(RE_SERVER);
|
|
if (server) {
|
|
params.serverId = server[1];
|
|
}
|
|
|
|
// Check for channel ID
|
|
const channel = pathname.match(RE_CHANNEL);
|
|
if (channel) {
|
|
params.channelId = channel[1];
|
|
}
|
|
|
|
// Check for message ID
|
|
const message = pathname.match(RE_MESSAGE_ID);
|
|
if (message) {
|
|
params.messageId = message[1];
|
|
}
|
|
|
|
// Check for bot ID
|
|
const bot = pathname.match(RE_BOT_ID);
|
|
if (bot) {
|
|
params.botId = bot[1];
|
|
}
|
|
|
|
return params;
|
|
}
|
|
|
|
/**
|
|
* Try to resolve route parameters regardless of the current position within component tree
|
|
*/
|
|
export function useSmartParams(): Accessor<GlobalParams> {
|
|
const location = useLocation();
|
|
return () => paramsFromPathname(location.pathname);
|
|
}
|