feat: loading files from manifest
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
"@trpc/next": "^10.43.6",
|
"@trpc/next": "^10.43.6",
|
||||||
"@trpc/react-query": "^10.43.6",
|
"@trpc/react-query": "^10.43.6",
|
||||||
"@trpc/server": "^10.43.6",
|
"@trpc/server": "^10.43.6",
|
||||||
|
"axios": "^1.6.7",
|
||||||
"drizzle-orm": "^0.29.3",
|
"drizzle-orm": "^0.29.3",
|
||||||
"next": "^14.0.4",
|
"next": "^14.0.4",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
|||||||
64
pnpm-lock.yaml
generated
64
pnpm-lock.yaml
generated
@@ -29,6 +29,9 @@ dependencies:
|
|||||||
'@trpc/server':
|
'@trpc/server':
|
||||||
specifier: ^10.43.6
|
specifier: ^10.43.6
|
||||||
version: 10.45.0
|
version: 10.45.0
|
||||||
|
axios:
|
||||||
|
specifier: ^1.6.7
|
||||||
|
version: 1.6.7
|
||||||
drizzle-orm:
|
drizzle-orm:
|
||||||
specifier: ^0.29.3
|
specifier: ^0.29.3
|
||||||
version: 0.29.3(@planetscale/database@1.13.0)(@types/react@18.2.47)(mysql2@3.7.0)(react@18.2.0)
|
version: 0.29.3(@planetscale/database@1.13.0)(@types/react@18.2.47)(mysql2@3.7.0)(react@18.2.0)
|
||||||
@@ -1320,6 +1323,10 @@ packages:
|
|||||||
has-symbols: 1.0.3
|
has-symbols: 1.0.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/asynckit@0.4.0:
|
||||||
|
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/autoprefixer@10.4.16(postcss@8.4.33):
|
/autoprefixer@10.4.16(postcss@8.4.33):
|
||||||
resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==}
|
resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==}
|
||||||
engines: {node: ^10 || ^12 || >=14}
|
engines: {node: ^10 || ^12 || >=14}
|
||||||
@@ -1346,6 +1353,16 @@ packages:
|
|||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/axios@1.6.7:
|
||||||
|
resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==}
|
||||||
|
dependencies:
|
||||||
|
follow-redirects: 1.15.5
|
||||||
|
form-data: 4.0.0
|
||||||
|
proxy-from-env: 1.1.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- debug
|
||||||
|
dev: false
|
||||||
|
|
||||||
/axobject-query@3.2.1:
|
/axobject-query@3.2.1:
|
||||||
resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==}
|
resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1492,6 +1509,13 @@ packages:
|
|||||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/combined-stream@1.0.8:
|
||||||
|
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||||
|
engines: {node: '>= 0.8'}
|
||||||
|
dependencies:
|
||||||
|
delayed-stream: 1.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/commander@4.1.1:
|
/commander@4.1.1:
|
||||||
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@@ -1586,6 +1610,11 @@ packages:
|
|||||||
object-keys: 1.1.1
|
object-keys: 1.1.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/delayed-stream@1.0.0:
|
||||||
|
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||||
|
engines: {node: '>=0.4.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/denque@2.1.0:
|
/denque@2.1.0:
|
||||||
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
|
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
|
||||||
engines: {node: '>=0.10'}
|
engines: {node: '>=0.10'}
|
||||||
@@ -2325,6 +2354,16 @@ packages:
|
|||||||
resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
|
resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/follow-redirects@1.15.5:
|
||||||
|
resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==}
|
||||||
|
engines: {node: '>=4.0'}
|
||||||
|
peerDependencies:
|
||||||
|
debug: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
debug:
|
||||||
|
optional: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/for-each@0.3.3:
|
/for-each@0.3.3:
|
||||||
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -2339,6 +2378,15 @@ packages:
|
|||||||
signal-exit: 4.1.0
|
signal-exit: 4.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/form-data@4.0.0:
|
||||||
|
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
||||||
|
engines: {node: '>= 6'}
|
||||||
|
dependencies:
|
||||||
|
asynckit: 0.4.0
|
||||||
|
combined-stream: 1.0.8
|
||||||
|
mime-types: 2.1.35
|
||||||
|
dev: false
|
||||||
|
|
||||||
/fraction.js@4.3.7:
|
/fraction.js@4.3.7:
|
||||||
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -2969,6 +3017,18 @@ packages:
|
|||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/mime-db@1.52.0:
|
||||||
|
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||||
|
engines: {node: '>= 0.6'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/mime-types@2.1.35:
|
||||||
|
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||||
|
engines: {node: '>= 0.6'}
|
||||||
|
dependencies:
|
||||||
|
mime-db: 1.52.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/minimatch@3.1.2:
|
/minimatch@3.1.2:
|
||||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3417,6 +3477,10 @@ packages:
|
|||||||
react-is: 16.13.1
|
react-is: 16.13.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/proxy-from-env@1.1.0:
|
||||||
|
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/punycode@2.3.1:
|
/punycode@2.3.1:
|
||||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
|
import { useApp } from "~/context/AppContext";
|
||||||
import { useTerminal } from "~/context/TerminalContext";
|
import { useTerminal } from "~/context/TerminalContext";
|
||||||
import { api } from "~/utils/api";
|
import { FILE_STYLES, File } from "~/utils/filesystem";
|
||||||
import { type Cell } from "~/utils/terminal/cell";
|
import { type Cell } from "~/utils/terminal/cell";
|
||||||
import { TerminalRenderer } from "~/utils/terminal/renderer";
|
import { TerminalRenderer } from "~/utils/terminal/renderer";
|
||||||
import { theme } from "~/utils/terminal/theme";
|
import { theme } from "~/utils/terminal/theme";
|
||||||
|
import { Manifest } from "~/utils/types";
|
||||||
|
|
||||||
const PATH_FOLDED: Cell = {
|
const PATH_FOLDED: Cell = {
|
||||||
char: "",
|
char: "",
|
||||||
@@ -15,36 +17,6 @@ const PATH_UNFOLDED: Cell = {
|
|||||||
foreground: theme.blue,
|
foreground: theme.blue,
|
||||||
};
|
};
|
||||||
|
|
||||||
const FILE_STYLES = {
|
|
||||||
directory: {
|
|
||||||
char: "\ue6ad", // \ue6ad ||| \ueaf6
|
|
||||||
foreground: theme.blue,
|
|
||||||
},
|
|
||||||
md: {
|
|
||||||
char: "\ue73e",
|
|
||||||
foreground: theme.blue,
|
|
||||||
},
|
|
||||||
asc: {
|
|
||||||
char: "\uf43d",
|
|
||||||
foreground: theme.yellow,
|
|
||||||
},
|
|
||||||
} as const satisfies Record<string, Cell>;
|
|
||||||
|
|
||||||
type FileType = keyof typeof FILE_STYLES;
|
|
||||||
|
|
||||||
type File = {
|
|
||||||
name: string;
|
|
||||||
} & (
|
|
||||||
| {
|
|
||||||
type: Exclude<FileType, "directory">;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: "directory";
|
|
||||||
children: Array<File>;
|
|
||||||
folded: boolean;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const FILES_SRC: Array<File> = [
|
const FILES_SRC: Array<File> = [
|
||||||
{
|
{
|
||||||
name: "projects",
|
name: "projects",
|
||||||
@@ -59,11 +31,39 @@ const FILES_SRC: Array<File> = [
|
|||||||
{ name: "pubkey.asc", type: "asc" },
|
{ name: "pubkey.asc", type: "asc" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const buildFileTree = (manifest: Manifest): Array<File> => {
|
||||||
|
if (manifest === undefined) return [];
|
||||||
|
|
||||||
|
const files: Array<File> = [];
|
||||||
|
manifest.projects.forEach(project => {
|
||||||
|
if (project.name === "pihkaal") {
|
||||||
|
project.files.forEach(file => {
|
||||||
|
files.push({
|
||||||
|
name: file,
|
||||||
|
type: "md",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
files.push({
|
||||||
|
name: project.name,
|
||||||
|
type: "directory",
|
||||||
|
folded: true,
|
||||||
|
children: project.files.map(file => ({
|
||||||
|
name: file,
|
||||||
|
type: "md",
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return files;
|
||||||
|
};
|
||||||
|
|
||||||
export const NvimTree = () => {
|
export const NvimTree = () => {
|
||||||
const { data: repos } = api.github.getRepos.useQuery();
|
const manifest = useApp();
|
||||||
|
|
||||||
const [selected, setSelected] = useState(0);
|
const [selected, setSelected] = useState(0);
|
||||||
const [files, setFiles] = useState(FILES_SRC);
|
const [files, setFiles] = useState(buildFileTree(manifest));
|
||||||
|
|
||||||
const { cols: width, rows: height } = useTerminal();
|
const { cols: width, rows: height } = useTerminal();
|
||||||
const canvas = new TerminalRenderer(width * 0.2, height - 2, {
|
const canvas = new TerminalRenderer(width * 0.2, height - 2, {
|
||||||
|
|||||||
39
src/context/AppContext.tsx
Normal file
39
src/context/AppContext.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import {
|
||||||
|
createContext,
|
||||||
|
useEffect,
|
||||||
|
useContext,
|
||||||
|
useState,
|
||||||
|
ReactNode,
|
||||||
|
} from "react";
|
||||||
|
import axios from "axios";
|
||||||
|
import { Manifest } from "~/utils/types";
|
||||||
|
|
||||||
|
const AppContext = createContext<Manifest | undefined>(undefined);
|
||||||
|
|
||||||
|
export const AppContextProvider = (props: {
|
||||||
|
children: Array<ReactNode> | ReactNode;
|
||||||
|
}) => {
|
||||||
|
const [manifest, setManifest] = useState<Manifest>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
axios
|
||||||
|
.get<Manifest>(
|
||||||
|
"https://raw.githubusercontent.com/pihkaal/pihkaal/main/manifest.json",
|
||||||
|
)
|
||||||
|
.then(x => {
|
||||||
|
setManifest(x.data);
|
||||||
|
console.log(x.data);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AppContext.Provider value={manifest}>{props.children}</AppContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useApp = () => {
|
||||||
|
const context = useContext(AppContext);
|
||||||
|
if (!context) throw new Error("useApp must be used inside the app lol");
|
||||||
|
|
||||||
|
return context;
|
||||||
|
};
|
||||||
@@ -3,10 +3,11 @@ import { Terminal } from "~/components/Terminal";
|
|||||||
import { MusicVisualizer } from "~/components/MusicVisualizer";
|
import { MusicVisualizer } from "~/components/MusicVisualizer";
|
||||||
import { MusicPlayer } from "~/components/MusicPlayer";
|
import { MusicPlayer } from "~/components/MusicPlayer";
|
||||||
import { Nvim } from "~/components/Nvim/Nvim";
|
import { Nvim } from "~/components/Nvim/Nvim";
|
||||||
|
import { AppContextProvider } from "~/context/AppContext";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<>
|
<AppContextProvider>
|
||||||
<Head>
|
<Head>
|
||||||
<title>pihkaal</title>
|
<title>pihkaal</title>
|
||||||
</Head>
|
</Head>
|
||||||
@@ -36,6 +37,6 @@ export default function Home() {
|
|||||||
</Terminal>
|
</Terminal>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</>
|
</AppContextProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,18 @@
|
|||||||
import { Octokit } from "@octokit/rest";
|
import { Octokit } from "@octokit/rest";
|
||||||
import { publicProcedure } from "../../trpc";
|
import { publicProcedure } from "../../trpc";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
type Manifest = {
|
||||||
|
projects: Array<{
|
||||||
|
name: string;
|
||||||
|
files: Array<string>;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
|
||||||
export const getRepos = publicProcedure.query(async () => {
|
export const getRepos = publicProcedure.query(async () => {
|
||||||
const octokit = new Octokit();
|
const { data: manifest } = await axios.get<Manifest>(
|
||||||
|
"https://raw.githubusercontent.com/pihkaal/pihkaal/main/manifest.json",
|
||||||
|
);
|
||||||
|
|
||||||
//const response = await octokit.repos.listForUser({ username: "pihkaal" });
|
return manifest;
|
||||||
//const repos = response.data.filter(x => x.name !== "pihkaal");
|
|
||||||
return [];
|
|
||||||
});
|
});
|
||||||
|
|||||||
32
src/utils/filesystem.ts
Normal file
32
src/utils/filesystem.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { Cell } from "./terminal/cell";
|
||||||
|
import { theme } from "./terminal/theme";
|
||||||
|
|
||||||
|
export const FILE_STYLES = {
|
||||||
|
directory: {
|
||||||
|
char: "\ue6ad", // \ue6ad ||| \ueaf6
|
||||||
|
foreground: theme.blue,
|
||||||
|
},
|
||||||
|
md: {
|
||||||
|
char: "\ue73e",
|
||||||
|
foreground: theme.blue,
|
||||||
|
},
|
||||||
|
asc: {
|
||||||
|
char: "\uf43d",
|
||||||
|
foreground: theme.yellow,
|
||||||
|
},
|
||||||
|
} as const satisfies Record<string, Cell>;
|
||||||
|
|
||||||
|
export type FileType = keyof typeof FILE_STYLES;
|
||||||
|
|
||||||
|
export type File = {
|
||||||
|
name: string;
|
||||||
|
} & (
|
||||||
|
| {
|
||||||
|
type: Exclude<FileType, "directory">;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: "directory";
|
||||||
|
children: Array<File>;
|
||||||
|
folded: boolean;
|
||||||
|
}
|
||||||
|
);
|
||||||
6
src/utils/types.ts
Normal file
6
src/utils/types.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export type Manifest = {
|
||||||
|
projects: Array<{
|
||||||
|
name: string;
|
||||||
|
files: Array<string>;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user