app shows treeview of server directory, click folder to expand or collapse files
//cmd - server log
C:\Users\bob\golang12\directory-app
[{C:\Users\bob\golang12\directory-app.git true} {C:\Users\bob\golang12\directory-app.gitignore false} {C:\Users\bob\golang12\directory-appcapacitor.config.json false} {C:\Users\bob\golang12\directory-appionic.config.json false} {C:\Users\bob\golang12\directory-appnode_modules true} {C:\Users\bob\golang12\directory-apppackage-lock.json false} {C:\Users\bob\golang12\directory-apppackage.json false} {C:\Users\bob\golang12\directory-apppublic true} {C:\Users\bob\golang12\directory-appsrc true} {C:\Users\bob\golang12\directory-apptsconfig.json false}]
//main.go
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
"path"
"path/filepath"
"runtime"
"sort"
"github.com/gorilla/mux"
)
type fileStruct struct {
Name string
IsDir bool
}
var projectPath = rootDir() + "\\golang12\\"
func indexGetHandler(w http.ResponseWriter, r *http.Request) {
dir := viewDirectory(projectPath)
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(dir)
}
func indexPostHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusCreated)
r.ParseForm()
fmt.Println(r.PostForm)
path := r.PostForm.Get("dir")
fmt.Println(path)
dir := viewDirectory(path)
json.NewEncoder(w).Encode(dir)
}
func rootDir() string {
_, b, _, _ := runtime.Caller(0)
d := path.Join(path.Dir(b))
return filepath.Dir(d)
}
func viewDirectory(dirname string) []fileStruct {
f, err := os.Open(dirname)
if err != nil {
//log.Fatal(err)
return []fileStruct{}
}
files, err := f.Readdir(-1)
f.Close()
if err != nil {
//log.Fatal(err)
return []fileStruct{}
}
var dir = []fileStruct{}
for _, file := range files {
name := dirname + file.Name()
dir = append(dir, fileStruct{Name: name, IsDir: file.IsDir()})
}
sort.SliceStable(dir, func(i, j int) bool {
return dir[i].Name < dir[j].Name
})
fmt.Println(dir)
return dir
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", indexGetHandler).Methods("GET")
r.HandleFunc("/", indexPostHandler).Methods("POST", "OPTIONS")
fs := http.FileServer(http.Dir("./static/"))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs))
http.Handle("/", r)
http.ListenAndServe(":8000", nil)
}
-----------------------------------------
//directory-app/src/pages/Home.js
import React, { useState, useEffect } from 'react';
import './Home.css';
import axios from 'axios'
import FolderDisplay from '../components/folderDisplay'
export default function Home() {
const [dir, setDir] = useState([])
useEffect(() => {
document.title = 'directory'
get_dir()
}, [])
function get_dir() {
axios({
method: 'get',
url: 'http://localhost:8000/',
})
.then(response => {
setDir(response.data)
})
.catch(function (error) {
alert(error);
setTimeout(() => {
get_dir()
}, 5000);
});
}
return (
<div style={{ overflowY: 'scroll', height: '100%' }}>
<h1>Server</h1>
<ul class="no-bullets">
{
dir.map((item, index) => {
const dir_split = item.Name.split("\\")
const folder_name = dir_split[dir_split.length - 1]
return <FolderDisplay name={folder_name} dir={item.Name} isDir={item.IsDir} />
})
}
</ul>
</div>
);
};
--------------------------------------
//directory-app/src/components/folderDisplay.js
import React, { useState } from 'react';
import { folder, folderOpenOutline, documentOutline } from 'ionicons/icons';
import { IonIcon } from '@ionic/react';
import axios from 'axios'
import '../pages/Home.css'
const qs = require('querystring')
export default function FolderDisplay(props) {
const [open, setOpen] = useState(false)
const [subDir, setSubDir] = useState([])
function post_dir(d) {
axios({
method: 'post',
url: 'http://localhost:8000/',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: qs.stringify({ dir: d })
})
.then(response => {
setSubDir(response.data)
})
.catch(function (error) {
alert(error);
});
}
function clickEvent() {
if (!props.isDir) { return }
if (!open) {
post_dir(props.dir)
}
setOpen(!open)
}
const folder_icon = open ? <IonIcon icon={folderOpenOutline} /> : <IonIcon icon={folder} />
const sub_folder_list = subDir.map((item, index) => {
const dir_split = item.Name.split("\\")
const folder_name = dir_split[dir_split.length - 1].replace(props.name, '')
const dir_name = item.Name.replace(folder_name, '') + '\\' + folder_name
return <li>
<FolderDisplay name={folder_name} dir={dir_name} isDir={item.IsDir} />
</li>
})
return (
<li >
<span onClick={() => clickEvent()}>
{props.isDir ? folder_icon : <IonIcon icon={documentOutline} />}{' '}
{props.name}
</span>
{open ? <ul class="no-bullets">
{sub_folder_list}
</ul> : null}
</li>
);
};
----------------------
//directory-app/src/pages/Home.css
ul.no-bullets {
list-style-type: none;
}
reference:
go json response
ionic react
go cross-origin
axios post x-www-form-urlencoded
No comments:
Post a Comment