mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-03-14 12:18:30 +03:00
Better resolving of links
This commit is contained in:
parent
1422c5da33
commit
7019c09e5b
2 changed files with 79 additions and 23 deletions
|
@ -1,34 +1,73 @@
|
|||
import { useLayoutEffect } from 'preact/hooks';
|
||||
import { useLayoutEffect, useState } from 'preact/hooks';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import Link from '../components/link';
|
||||
import getInstanceStatusURL from '../utils/get-instance-status-url';
|
||||
import Loader from '../components/loader';
|
||||
import { api } from '../utils/api';
|
||||
import getInstanceStatusURL, {
|
||||
getInstanceStatusObject,
|
||||
} from '../utils/get-instance-status-url';
|
||||
|
||||
export default function HttpRoute() {
|
||||
const location = useLocation();
|
||||
const url = location.pathname.replace(/^\//, '');
|
||||
const statusURL = getInstanceStatusURL(url);
|
||||
const statusObject = getInstanceStatusObject(url);
|
||||
// const statusURL = getInstanceStatusURL(url);
|
||||
const statusURL = statusObject?.instance
|
||||
? `/${statusObject.instance}/s/${statusObject.id}`
|
||||
: null;
|
||||
const [uiState, setUIState] = useState('loading');
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (statusURL) {
|
||||
setTimeout(() => {
|
||||
window.location.hash = statusURL + '?view=full';
|
||||
}, 300);
|
||||
}
|
||||
setUIState('loading');
|
||||
(async () => {
|
||||
const { instance, id } = statusObject;
|
||||
const { masto } = api({ instance });
|
||||
|
||||
// Check if status returns 200
|
||||
try {
|
||||
const status = await masto.v1.statuses.$select(id).fetch();
|
||||
if (status) {
|
||||
window.location.hash = statusURL + '?view=full';
|
||||
return;
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
// Fallback to search
|
||||
{
|
||||
const { masto: currentMasto, instance: currentInstance } = api();
|
||||
const result = await currentMasto.v2.search.fetch({
|
||||
q: url,
|
||||
type: 'statuses',
|
||||
limit: 1,
|
||||
resolve: true,
|
||||
});
|
||||
if (result.statuses.length) {
|
||||
const status = result.statuses[0];
|
||||
window.location.hash = `/${currentInstance}/s/${status.id}?view=full`;
|
||||
} else {
|
||||
// Fallback to original URL, which will probably show error
|
||||
window.location.hash = statusURL + '?view=full';
|
||||
}
|
||||
}
|
||||
})();
|
||||
}, [statusURL]);
|
||||
|
||||
return (
|
||||
<div class="ui-state" tabIndex="-1">
|
||||
{statusURL ? (
|
||||
{uiState === 'loading' ? (
|
||||
<>
|
||||
<h2>Redirecting…</h2>
|
||||
<Loader abrupt />
|
||||
<h2>Resolving…</h2>
|
||||
<p>
|
||||
<a href={`#${statusURL}?view=full`}>{statusURL}</a>
|
||||
<a href={url} target="_blank" rel="noopener noreferrer">
|
||||
{url}
|
||||
</a>
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<h2>Unable to process URL</h2>
|
||||
<h2>Unable to resolve URL</h2>
|
||||
<p>
|
||||
<a href={url} target="_blank" rel="noopener noreferrer">
|
||||
{url}
|
||||
|
|
|
@ -1,19 +1,36 @@
|
|||
export const statusRegex = /\/@([^@\/]+)@?([^\/]+)?\/([^\/]+)\/?$/i;
|
||||
export const statusNoteRegex = /\/notes\/([^\/]+)\/?$/i;
|
||||
function getInstanceStatusURL(url) {
|
||||
// export const statusRegex = /\/@([^@\/]+)@?([^\/]+)?\/([^\/]+)\/?$/i;
|
||||
// export const statusNoteRegex = /\/notes\/([^\/]+)\/?$/i;
|
||||
|
||||
const statusPostRegexes = [
|
||||
/^\/@[^@\/]+\/(?:statuses|posts)\/([^\/]+)/i, // GoToSocial, Takahe
|
||||
/\/notes\/([^\/]+)/i, // Misskey, Firefish
|
||||
/^\/(?:notice|objects)\/([a-z0-9-]+)/i, // Pleroma
|
||||
/\/@[^@\/]+@?[^\/]+?\/([^\/]+)/i, // Mastodon
|
||||
];
|
||||
|
||||
export function getInstanceStatusObject(url) {
|
||||
// Regex /:username/:id, where username = @username or @username@domain, id = anything
|
||||
const { hostname, pathname } = new URL(url);
|
||||
const [, username, domain, id] = pathname.match(statusRegex) || [];
|
||||
|
||||
if (id) {
|
||||
return `/${hostname}/s/${id}`;
|
||||
// const [, username, domain, id] = pathname.match(statusRegex) || [];
|
||||
for (const regex of statusPostRegexes) {
|
||||
const [, id] = pathname.match(regex) || [];
|
||||
console.log(pathname, regex, id);
|
||||
if (id) {
|
||||
return {
|
||||
instance: hostname,
|
||||
id,
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const [, noteId] = pathname.match(statusNoteRegex) || [];
|
||||
|
||||
if (noteId) {
|
||||
return `/${hostname}/s/${noteId}`;
|
||||
function getInstanceStatusURL(url) {
|
||||
const { instance, id } = getInstanceStatusObject(url);
|
||||
if (instance && id) {
|
||||
return `/${instance}/s/${id}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export default getInstanceStatusURL;
|
||||
|
|
Loading…
Add table
Reference in a new issue