feat: list file contents
This commit is contained in:
38
api/main.go
38
api/main.go
@@ -1,11 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
// "fmt"
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"encoding/base64"
|
||||
|
||||
"net/http"
|
||||
|
||||
@@ -17,7 +18,7 @@ func main() {
|
||||
router := gin.Default()
|
||||
router.SetTrustedProxies([]string{"127.0.0.1"}) // TODO: fix All origins allowed by default
|
||||
router.Use(cors.Default())
|
||||
list := listFiles("/Users/madundead/Syncthing/Obsidian/Personal")
|
||||
list := listFiles("/home/madundead/Syncthing/Obsidian/Personal")
|
||||
|
||||
router.GET("/api/v1/files", func(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
@@ -26,6 +27,21 @@ func main() {
|
||||
})
|
||||
})
|
||||
|
||||
router.GET("/api/v1/files/:id", func(c *gin.Context) {
|
||||
id := c.Params.ByName("id")
|
||||
// value, ok := db[user]
|
||||
// if ok {
|
||||
path, _ := base64.StdEncoding.DecodeString(id)
|
||||
|
||||
data, _ := os.ReadFile(string(path))
|
||||
// fmt.Print(string(dat))
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"data": string(data)})
|
||||
// } else {
|
||||
// c.JSON(http.StatusOK, gin.H{"user": user, "status": "no value"})
|
||||
// }
|
||||
})
|
||||
|
||||
if err := router.Run(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -46,12 +62,12 @@ func listFiles(dir string) []string {
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
func readFile(string filePath) []string {
|
||||
content, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
fmt.Println("Error reading file:", err)
|
||||
return
|
||||
}
|
||||
return content
|
||||
}
|
||||
//
|
||||
// func readFile(string filePath) []string {
|
||||
// content, err := os.ReadFile(filePath)
|
||||
// if err != nil {
|
||||
// fmt.Println("Error reading file:", err)
|
||||
// return
|
||||
// }
|
||||
// return content
|
||||
// }
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// import { FilesList } from "./components/FilesList";
|
||||
// import { FileContent } from "./components/FileContent";
|
||||
import { Root } from "./components/Root";
|
||||
import { Obi } from "./components/Obi";
|
||||
import "./index.css";
|
||||
|
||||
export function App() {
|
||||
return (<Root/ >);
|
||||
return (<Obi />);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -8,7 +8,7 @@ export function FileContent({ filePath }) {
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const response = await fetch("http://localhost:8912/api/v1/files"); // Replace with your API endpoint
|
||||
const response = await fetch("http://localhost:8912/api/v1/files/" + filePath); // Replace with your API endpoint
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
@@ -22,14 +22,14 @@ export function FileContent({ filePath }) {
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, []); // Empty dependency array ensures this effect runs only once on mount
|
||||
}, [filePath]); // Empty dependency array ensures this effect runs only once on mount
|
||||
|
||||
if (loading) return <p>Loading data...</p>;
|
||||
if (error) return <p>Error: {error.message}</p>;
|
||||
// if (error) return <p>Error: {error.message}</p>;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<pre>{filePath}</pre>
|
||||
<pre>{data?.data}</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
export function FilesList({ handleFileClick }) {
|
||||
const [data, setData] = useState(null);
|
||||
@@ -27,15 +27,11 @@ export function FilesList({ handleFileClick }) {
|
||||
if (loading) return <p>Loading data...</p>;
|
||||
if (error) return <p>Error: {error.message}</p>;
|
||||
|
||||
const onClick = (event) => {
|
||||
handleFileClick(event.target.value); // Call the parent's callback with the new value
|
||||
};
|
||||
|
||||
const listFiles = data.map(filePath => <li onClick={onClick} className="cursor-pointer">{filePath}</li>);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{listFiles}
|
||||
{data.map(filePath => (
|
||||
<li key={filePath} onClick={() => handleFileClick(filePath)} className="cursor-pointer">{filePath}</li>)
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
24
frontend/src/components/Obi.tsx
Normal file
24
frontend/src/components/Obi.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { useState } from 'react';
|
||||
import { FilesList } from "./FilesList";
|
||||
import { FileContent } from "./FileContent";
|
||||
import { bytesToBase64 } from "../util/codecs.ts";
|
||||
|
||||
export function Obi() {
|
||||
const [filePath, setFilePath] = useState('');
|
||||
|
||||
const handleFileClick = (value) => {
|
||||
console.log(`Encoded string: [${bytesToBase64(value)}]`);
|
||||
setFilePath(bytesToBase64(value));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="grid text-black grid-cols-1 md:grid-cols-2 h-screen">
|
||||
<div className="bg-gray-100 p-4 overflow-y-auto">
|
||||
<FilesList handleFileClick={handleFileClick} />
|
||||
</div>
|
||||
<div className="bg-white p-4 overflow-y-auto">
|
||||
<FileContent filePath={filePath} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
import { FilesList } from "./FilesList";
|
||||
import { FileContent } from "./FileContent";
|
||||
|
||||
export function Root() {
|
||||
const [filePath, setFilePath] = useState(''); // State to be shared
|
||||
|
||||
const handleFileClick = () => {
|
||||
setFilePath('1000')
|
||||
alert("Button clicked!");
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex">
|
||||
<div className="flex-1">
|
||||
<FilesList onClick={handleFileClick} />
|
||||
</div>
|
||||
<div className="flex-2">
|
||||
<FileContent filePath={filePath} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
12
frontend/src/util/codecs.ts
Normal file
12
frontend/src/util/codecs.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem.
|
||||
export function base64ToBytes(base64) {
|
||||
const binString = atob(base64);
|
||||
return Uint8Array.from(binString, (m) => m.codePointAt(0));
|
||||
}
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem.
|
||||
export function bytesToBase64(string: String) {
|
||||
const bytes = new TextEncoder().encode(string)
|
||||
const binString = String.fromCodePoint(...bytes);
|
||||
return btoa(binString);
|
||||
}
|
||||
Reference in New Issue
Block a user