Wednesday, 18 November 2020

golang 21 ionic react directory tree view

 code linkhttps://github.com/chuanshuoge6/go-ionic-directory
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