From 9b0d48214bf7c7b7f9104ba7729ce890973a9fb3 Mon Sep 17 00:00:00 2001 From: Kostiantyn Bukliei Date: Fri, 17 Oct 2025 21:21:19 +0300 Subject: [PATCH] feat: list file contents --- api/main.go | 38 ++++++++++++++++++------- frontend/src/App.tsx | 4 +-- frontend/src/components/FileContent.tsx | 8 +++--- frontend/src/components/FilesList.tsx | 12 +++----- frontend/src/components/Obi.tsx | 24 ++++++++++++++++ frontend/src/components/Root.tsx | 24 ---------------- frontend/src/util/codecs.ts | 12 ++++++++ 7 files changed, 73 insertions(+), 49 deletions(-) create mode 100644 frontend/src/components/Obi.tsx delete mode 100644 frontend/src/components/Root.tsx create mode 100644 frontend/src/util/codecs.ts diff --git a/api/main.go b/api/main.go index abcacab..bbf20d3 100644 --- a/api/main.go +++ b/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 +// } diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index dd90b3b..18d2057 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -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 (); + return (); } export default App; diff --git a/frontend/src/components/FileContent.tsx b/frontend/src/components/FileContent.tsx index 8cfa1f8..b6e8188 100644 --- a/frontend/src/components/FileContent.tsx +++ b/frontend/src/components/FileContent.tsx @@ -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

Loading data...

; - if (error) return

Error: {error.message}

; + // if (error) return

Error: {error.message}

; return (
-
{filePath}
+
{data?.data}
); } diff --git a/frontend/src/components/FilesList.tsx b/frontend/src/components/FilesList.tsx index aee9a57..c8c83f0 100644 --- a/frontend/src/components/FilesList.tsx +++ b/frontend/src/components/FilesList.tsx @@ -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

Loading data...

; if (error) return

Error: {error.message}

; - const onClick = (event) => { - handleFileClick(event.target.value); // Call the parent's callback with the new value - }; - - const listFiles = data.map(filePath =>
  • {filePath}
  • ); - return (
    - {listFiles} + {data.map(filePath => ( +
  • handleFileClick(filePath)} className="cursor-pointer">{filePath}
  • ) + )}
    ); } diff --git a/frontend/src/components/Obi.tsx b/frontend/src/components/Obi.tsx new file mode 100644 index 0000000..c85d92f --- /dev/null +++ b/frontend/src/components/Obi.tsx @@ -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 ( +
    +
    + +
    +
    + +
    +
    + ); +} diff --git a/frontend/src/components/Root.tsx b/frontend/src/components/Root.tsx deleted file mode 100644 index b71550f..0000000 --- a/frontend/src/components/Root.tsx +++ /dev/null @@ -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 ( -
    -
    - -
    -
    - -
    -
    - ); -} diff --git a/frontend/src/util/codecs.ts b/frontend/src/util/codecs.ts new file mode 100644 index 0000000..c741ec3 --- /dev/null +++ b/frontend/src/util/codecs.ts @@ -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); +}