mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-15 19:30:38 +08:00
@@ -85,6 +85,7 @@
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-namespace": ["error", { "allowDeclarations": true }],
|
||||
"@typescript-eslint/semi": ["error"],
|
||||
"@typescript-eslint/member-delimiter-style": [
|
||||
"error",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/// <reference types="cypress" />
|
||||
import { MockProvider } from "@rsksmart/mock-web3-provider";
|
||||
import { getPath } from "../support/e2e";
|
||||
|
||||
const groupedCommits = [
|
||||
{
|
||||
@@ -146,7 +147,7 @@ describe("project commits", () => {
|
||||
|
||||
it("display commit details", () => {
|
||||
cy.location().should(location => {
|
||||
expect(location.pathname).to.eq(
|
||||
expect(getPath(location)).to.eq(
|
||||
"/seeds/willow.radicle.garden/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/commits/cbf5df499ab4f4a908f1756fbe2c236a4530516a",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/// <reference types="cypress" />
|
||||
import { MockProvider } from "@rsksmart/mock-web3-provider";
|
||||
import { getPath } from "../support/e2e";
|
||||
|
||||
describe("project header", () => {
|
||||
beforeEach(() => {
|
||||
@@ -114,7 +115,7 @@ describe("project header", () => {
|
||||
"@projectReadme",
|
||||
]);
|
||||
cy.location().should(location => {
|
||||
expect(location.pathname).to.eq(
|
||||
expect(getPath(location)).to.eq(
|
||||
"/seeds/willow.radicle.garden/bright-forest-protocol/remotes/hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke/tree",
|
||||
);
|
||||
});
|
||||
@@ -135,7 +136,7 @@ describe("project header", () => {
|
||||
.click();
|
||||
cy.wait(["@projectTreecbf5df4", "@projectReadme"]);
|
||||
cy.location().should(location => {
|
||||
expect(location.pathname).to.eq(
|
||||
expect(getPath(location)).to.eq(
|
||||
"/seeds/willow.radicle.garden/bright-forest-protocol/remotes/hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke/tree/master",
|
||||
);
|
||||
});
|
||||
@@ -149,7 +150,7 @@ describe("project header", () => {
|
||||
.click();
|
||||
cy.wait(["@projectCommits"]);
|
||||
cy.location().should(location => {
|
||||
expect(location.pathname).to.eq(
|
||||
expect(getPath(location)).to.eq(
|
||||
"/seeds/willow.radicle.garden/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/remotes/hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke/history/master",
|
||||
);
|
||||
});
|
||||
@@ -160,7 +161,7 @@ describe("project header", () => {
|
||||
cy.get('[aria-label="Issue count"]').click();
|
||||
cy.wait(["@projectIssues"]);
|
||||
cy.location().should(location => {
|
||||
expect(location.pathname).to.eq(
|
||||
expect(getPath(location)).to.eq(
|
||||
"/seeds/willow.radicle.garden/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/remotes/hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke/issues",
|
||||
);
|
||||
});
|
||||
@@ -171,7 +172,7 @@ describe("project header", () => {
|
||||
cy.get('[aria-label="Patch count"]').click();
|
||||
cy.wait(["@projectPatches"]);
|
||||
cy.location().should(location => {
|
||||
expect(location.pathname).to.eq(
|
||||
expect(getPath(location)).to.eq(
|
||||
"/seeds/willow.radicle.garden/rad:git:hnrk8mbpirp7ua7sy66o4t9soasbq4y8uwgoy/remotes/hyndc7nx9keq76p1bkw9831arcndeeu3trwsc7kxt3osmpi6j9oeke/patches",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -5,4 +5,9 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
function getPath(location: Location): string {
|
||||
const url = location.href.replace(window.origin, "");
|
||||
return process.env.hashRouting ? url.substring(2) : url;
|
||||
}
|
||||
|
||||
export { getPath };
|
||||
|
||||
+3
-1
@@ -2,8 +2,10 @@
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
"start:ipfs": "HASH_ROUTING=1 vite --base ./",
|
||||
"serve": "vite preview",
|
||||
"build": "scripts/build",
|
||||
"build": "vite build",
|
||||
"build:ipfs": "HASH_ROUTING=1 vite build --base ./",
|
||||
"postinstall": "scripts/copy-katex-assets && scripts/install-twemoji-assets",
|
||||
"check": "scripts/check",
|
||||
"format": "npx prettier '**/*.@(ts|js|svelte|json|css|html)' --ignore-path .gitignore --write",
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
vite build
|
||||
cp _redirects build/_redirects
|
||||
@@ -2,18 +2,19 @@
|
||||
import type { Blob } from "@app/project";
|
||||
import type { ProjectRoute } from "@app/router/definitions";
|
||||
|
||||
import Readme from "@app/base/projects/Readme.svelte";
|
||||
import HeaderToggleLabel from "@app/base/projects/HeaderToggleLabel.svelte";
|
||||
import ProjectLink from "@app/router/ProjectLink.svelte";
|
||||
import Readme from "@app/base/projects/Readme.svelte";
|
||||
import { isMarkdownPath, scrollIntoView, twemoji } from "@app/utils";
|
||||
import { onMount } from "svelte";
|
||||
import { updateProjectRoute } from "@app/router";
|
||||
|
||||
export let blob: Blob;
|
||||
export let line: string | null;
|
||||
export let getImage: (path: string) => Promise<Blob>;
|
||||
export let activeRoute: ProjectRoute;
|
||||
export let blob: Blob;
|
||||
export let getImage: (path: string) => Promise<Blob>;
|
||||
export let line: string | undefined = undefined;
|
||||
|
||||
$: lineNumber = line ? parseInt(line.substring(1)) : null;
|
||||
$: lineNumber = line ? parseInt(line.substring(1)) : undefined;
|
||||
|
||||
const lastCommit = blob.info.lastCommit;
|
||||
const lines = blob.binary ? 0 : (blob.content.match(/\n/g) || []).length;
|
||||
@@ -25,16 +26,23 @@
|
||||
?.values()
|
||||
.next().value;
|
||||
|
||||
$: if (line) {
|
||||
scrollIntoView(line);
|
||||
}
|
||||
// Waiting onMount, due to the line numbers still loading.
|
||||
onMount(() => {
|
||||
if (line) {
|
||||
scrollIntoView(line);
|
||||
}
|
||||
});
|
||||
const isMarkdown = isMarkdownPath(blob.path);
|
||||
// If we have a line number we should show the raw output.
|
||||
let showMarkdown = line ? false : isMarkdown;
|
||||
const toggleMarkdown = () => {
|
||||
updateProjectRoute({ hash: undefined });
|
||||
updateProjectRoute({ line: undefined });
|
||||
showMarkdown = !showMarkdown;
|
||||
};
|
||||
|
||||
$: if (line) {
|
||||
scrollIntoView(line);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@@ -215,7 +223,7 @@
|
||||
<div class="line-numbers">
|
||||
{#each lineNumbers as lineNumber}
|
||||
<ProjectLink
|
||||
projectParams={{ hash: `L${lineNumber}` }}
|
||||
projectParams={{ line: `L${lineNumber}` }}
|
||||
id="L{lineNumber}">
|
||||
<span class="line-number" class:highlighted={lineNumber === line} />
|
||||
{lineNumber}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
export let activeRoute: ProjectRoute;
|
||||
|
||||
$: path = activeRoute.params.path || "/";
|
||||
$: line = activeRoute.params.hash || null;
|
||||
$: line = activeRoute.params.line;
|
||||
|
||||
// When the component is loaded the first time, the blob is yet to be loaded.
|
||||
let state: State = { status: Status.Loading, path };
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
router.updateProjectRoute({
|
||||
revision,
|
||||
path,
|
||||
line: activeRoute.params.line,
|
||||
hash: activeRoute.params.hash,
|
||||
route: undefined,
|
||||
});
|
||||
|
||||
@@ -4,4 +4,12 @@ const app = new App({
|
||||
target: document.body,
|
||||
});
|
||||
|
||||
declare global {
|
||||
namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
hashRouting: number;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default app;
|
||||
|
||||
@@ -19,6 +19,7 @@ export interface ProjectsParams {
|
||||
| { resource: "patch"; params: { patch: string } }
|
||||
| { resource: "patches" };
|
||||
hash?: string;
|
||||
line?: string;
|
||||
path?: string;
|
||||
peer?: string;
|
||||
profile?: string;
|
||||
|
||||
+33
-7
@@ -16,6 +16,13 @@ export const activeRouteStore: Readable<Route> = derived(
|
||||
},
|
||||
);
|
||||
|
||||
// Gets triggered when clicking on an anchor hash tag e.g. <a href="#header"/>
|
||||
// Allows the jump to a anchor hash
|
||||
window.addEventListener("hashchange", e => {
|
||||
const url = new URL(e.newURL);
|
||||
updateProjectRoute({ hash: url.hash.substring(1) });
|
||||
});
|
||||
|
||||
// Replaces history on any user interaction with forward and backwards buttons
|
||||
// with the current window.history.state
|
||||
window.addEventListener("popstate", e => {
|
||||
@@ -30,6 +37,7 @@ export function createProjectRoute(
|
||||
resource: "projects",
|
||||
params: {
|
||||
...activeRoute.params,
|
||||
line: undefined,
|
||||
hash: undefined,
|
||||
...projectRouteParams,
|
||||
},
|
||||
@@ -71,7 +79,12 @@ export const push = (newRoute: Route): void => {
|
||||
// Limit history to a maximum of 10 steps. We shouldn't be doing more than
|
||||
// one subsequent pop() anyway.
|
||||
historyStore.set([...history, newRoute].slice(-10));
|
||||
window.history.pushState(newRoute, documentTitle, routeToPath(newRoute));
|
||||
|
||||
const path = process.env.hashRouting
|
||||
? "#" + routeToPath(newRoute)
|
||||
: routeToPath(newRoute);
|
||||
|
||||
window.history.replaceState(newRoute, documentTitle, path);
|
||||
};
|
||||
|
||||
export const pop = (): void => {
|
||||
@@ -85,7 +98,12 @@ export const pop = (): void => {
|
||||
|
||||
export function replace(newRoute: Route): void {
|
||||
historyStore.set([newRoute]);
|
||||
window.history.replaceState(newRoute, documentTitle, routeToPath(newRoute));
|
||||
|
||||
const path = process.env.hashRouting
|
||||
? "#" + routeToPath(newRoute)
|
||||
: routeToPath(newRoute);
|
||||
|
||||
window.history.replaceState(newRoute, documentTitle, path);
|
||||
}
|
||||
|
||||
export const initialize = () => {
|
||||
@@ -107,8 +125,9 @@ function pathToRoute(path: string): Route | null {
|
||||
}
|
||||
|
||||
const url = new URL(path, window.origin);
|
||||
// Pathname starts usually with a "/", we remove it to avoid bad interpretations
|
||||
const segments = url.pathname.substring(1).split("/");
|
||||
const segments = process.env.hashRouting
|
||||
? url.hash.substring(2).split("#")[0].split("/") // Try to remove any additional hashes at the end of the URL.
|
||||
: url.pathname.substring(1).split("/");
|
||||
|
||||
const resource = segments.shift();
|
||||
switch (resource) {
|
||||
@@ -274,7 +293,9 @@ export function routeToPath(route: Route) {
|
||||
if (route.params.path && route.params.path !== "/") {
|
||||
suffix += `/${route.params.path}`;
|
||||
}
|
||||
if (route.params.hash) {
|
||||
if (route.params.line) {
|
||||
suffix += `#${route.params.line}`;
|
||||
} else if (route.params.hash) {
|
||||
suffix += `#${route.params.hash}`;
|
||||
}
|
||||
if (route.params.search) {
|
||||
@@ -285,7 +306,9 @@ export function routeToPath(route: Route) {
|
||||
if (route.params.search) {
|
||||
suffix += `${route.params.search}`;
|
||||
}
|
||||
if (route.params.hash) {
|
||||
if (route.params.line) {
|
||||
suffix += `#${route.params.line}`;
|
||||
} else if (route.params.hash) {
|
||||
suffix += `#${route.params.hash}`;
|
||||
}
|
||||
}
|
||||
@@ -343,13 +366,16 @@ function resolveProjectRoute(
|
||||
}
|
||||
|
||||
if (content === "tree") {
|
||||
const line = url.href.match(/#L\d+$/)?.pop();
|
||||
const hash = url.href.match(/#{1}[^#.]+$/)?.pop();
|
||||
return {
|
||||
view: { resource: "tree" },
|
||||
urn,
|
||||
peer,
|
||||
path: undefined,
|
||||
revision: undefined,
|
||||
hash: url.hash.substring(1),
|
||||
line: line?.substring(1),
|
||||
hash: hash?.substring(1),
|
||||
route: segments.join("/"),
|
||||
};
|
||||
} else if (content === "history") {
|
||||
|
||||
+7
-4
@@ -1,8 +1,8 @@
|
||||
///<reference types="vitest" />
|
||||
import path from "path";
|
||||
import type { UserConfig } from "vite";
|
||||
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
||||
import path from "path";
|
||||
import pluginRewriteAll from "vite-plugin-rewrite-all";
|
||||
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
||||
|
||||
const config: UserConfig = {
|
||||
optimizeDeps: {
|
||||
@@ -38,8 +38,11 @@ const config: UserConfig = {
|
||||
},
|
||||
},
|
||||
define: {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
"process.env": { READABLE_STREAM: "disable" },
|
||||
"process.env": {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
READABLE_STREAM: "disable",
|
||||
hashRouting: Boolean(process.env.HASH_ROUTING),
|
||||
},
|
||||
},
|
||||
build: {
|
||||
outDir: "build",
|
||||
|
||||
Reference in New Issue
Block a user