Skip to content

Commit

Permalink
Merge pull request #11 from thomscoder/directorySupport
Browse files Browse the repository at this point in the history
Directory support (initial)
  • Loading branch information
thomscoder authored Oct 9, 2022
2 parents 17ba21e + 7835149 commit 69a334b
Show file tree
Hide file tree
Showing 13 changed files with 184 additions and 20 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Quickly upload, create, open, read, modify and download files, on the fly.

Harmony also keep tracks of your changes or "workspaces" through git branches and git commits, all in-memory in your browser.

<img src="https://i.ibb.co/brDw78C/Schermata-2022-10-08-alle-14-56-53.png" width=80% />
<img src="https://i.ibb.co/pRbfJwT/Schermata-2022-10-09-alle-14-51-59-min.png" width=80% />

> Just me experimenting with WebAssembly.
<br/>
Expand Down
Binary file modified client/public/helpers/wasm/main.wasm
Binary file not shown.
47 changes: 47 additions & 0 deletions client/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@
transition: all 0.3s ease;
}

.virtual-file-wrapper svg path {
stroke: #000;
stroke-width: 5;
}

.virtual-file-wrapper.dir svg path {
fill: #ffca8e;
}

.virtual-file-wrapper:hover {
background-color: rgba(68, 214, 255, 0.3);
border: 0.01em solid white;
Expand Down Expand Up @@ -83,8 +92,46 @@ input[type='file'] {
overflow-y: auto;
}

.files-area.dir-open {
position: relative;
background-color: rgba(30, 30, 30, 0.9);
width: 70%;
height: 70vh;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

.files-area.dir-open .dir-menu {
border: solid #f4f4ff;
background-color: #1e1e1e;
position: absolute;
top: 0;
width: 100%;
text-align: center;
z-index: 1;
}

.files-area.dir-open .dir-menu svg {
position: absolute;
left: 2em;
height: 100%;
cursor: pointer;
}

.file {
text-align: center;
background-color: #1e1e1e;
padding: 0.2em 0.5em;
}

@media screen and (max-width: 768px) {
.file-selectors p + div form {
text-align: center;
}
.files-area.dir-open {
background-color: #1e1e1e;
width: 100%;
}
}
69 changes: 51 additions & 18 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import Draggable from 'react-draggable';
import { isMobile } from 'react-device-detect';

import { IoMdDocument as DocumentIcon } from '@react-icons/all-files/io/IoMdDocument';
import { IoIosFolderOpen as FolderIcon } from '@react-icons/all-files/io/IoIosFolderOpen';
import { AiOutlineArrowLeft as BackArrowIcon } from '@react-icons/all-files/ai/AiOutlineArrowLeft';

import { useRecoilValue, useSetRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
import { actionState, freeModeDisabledState, virtualFilesState } from './atoms/atoms';
import { openVirtualFilesWrapper, saveVirtualFilesWrapper } from './utils/goFunctions';
import { exploreDirectoryWrapper, isDirectoryWrapper, openVirtualFilesWrapper, saveVirtualFilesWrapper } from './utils/goFunctions';
import Actions from './components/Actions/Actions';

import Files from './components/Files/Files';
Expand All @@ -19,21 +21,37 @@ import { keyChecker } from './utils/utilityFunctions';
import './App.css';

function App() {
const virtualFiles = useRecoilValue(virtualFilesState);
const [virtualFiles, setVirtualFiles] = useRecoilState(virtualFilesState);
const setAction = useSetRecoilState(actionState);
const freeModeDisabled = useRecoilValue(freeModeDisabledState);

const [editorContent, setEditorContent] = useState<string>('');
const [openFile, setOpenFile] = useState<string>('');
const [prevOpenedFiles, setPrevOpenedFiles] = useState<Array<string>>([]);
const [openDir, setOpenDir] = useState<string>('');
const [oldVirtualFiles, setOldVirtualFiles] = useState<Array<never>>([]);

const clickOnFileHandler = (virtualFile: never) => {
// Get the file content from Go functions
// Open the file
// DEPRECATED: keep track of prev opened files (put that to color them differently or for future usages)
setEditorContent(openVirtualFilesWrapper(virtualFile));
setOpenFile(virtualFile);
setPrevOpenedFiles((prev: Array<string>) => [...prev, virtualFile]);
const goBackInDirectories = () => {
if (oldVirtualFiles.length > 0) {
setVirtualFiles([...oldVirtualFiles]);
return setOldVirtualFiles([]);
}
};

const clickOnFileHandler = (virtualFile: never, isDirectory: boolean = false) => {
if (!isDirectory) {
// Get the file content from Go functions
// Open the file
setEditorContent(openVirtualFilesWrapper(virtualFile));
setPrevOpenedFiles((prev: Array<string>) => [...prev, virtualFile]);
setOpenFile(virtualFile);
} else {
// Keep track of the directory you open to go back
setOldVirtualFiles(virtualFiles);
// Explore direcory
setVirtualFiles(exploreDirectoryWrapper(virtualFile) as never[]);
setOpenDir(virtualFile);
}
};

const saveChanges = (content: string) => {
Expand All @@ -55,10 +73,13 @@ function App() {

useEffect(() => {
window.addEventListener('keydown', keyboardShortcut);
if (localStorage.getItem('harmony-tutorial')) {
localStorage.removeItem('harmony-tutorial');
}
// Show the tutorial
if (!localStorage.getItem('harmony-tutorial')) {
if (!localStorage.getItem('new-harmony-tutorial')) {
setAction(HELP);
localStorage.setItem('harmony-tutorial', 'true');
localStorage.setItem('new-harmony-tutorial', 'true');
}

return () => {
Expand All @@ -72,20 +93,32 @@ function App() {
<Actions />
<Files />
<div className="App">
<div className="files-area" style={filesAreaStyle}>
<div className={`files-area ${oldVirtualFiles.length > 0 ? 'dir-open' : ''}`} style={filesAreaStyle}>
{oldVirtualFiles.length > 0 && (
<div className="dir-menu">
{openDir}
<BackArrowIcon onClick={goBackInDirectories} />
</div>
)}
{virtualFiles.map((virtualFile, index) => {
// Check if directory
const isDirectory = isDirectoryWrapper(virtualFile);
// Check if file was prev opened
const prevOpened = !!prevOpenedFiles.find((f) => f === virtualFile) ? 'modified' : '';
// Regex on name
const virtualFileName = (virtualFile as string).split('/').at(-1);
// Double click on files to open (on mobile should disable the drag - from the menu)
return (
<Draggable key={index} bounds="parent" disabled={freeModeDisabled}>
<div
onDoubleClick={() => {
clickOnFileHandler(virtualFile);
clickOnFileHandler(virtualFile, isDirectory);
}}
className={`virtual-file-wrapper ${!!prevOpenedFiles.find((f) => f === virtualFile) ? 'modified' : ''}`}
className={`virtual-file-wrapper ${prevOpened} ${isDirectory ? 'dir' : ''}`}
>
<DocumentIcon size={60} />
<div key={index} className="file">
{virtualFile}
{isDirectory ? <FolderIcon size={60} /> : <DocumentIcon size={60} />}
<div key={index} className={`file`}>
{virtualFileName}
</div>
</div>
</Draggable>
Expand Down
4 changes: 3 additions & 1 deletion client/src/components/Git/GitGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ const GitGraph = () => {
});

gitFootPrints.forEach((footPrint: gitFootPrintType, index: number) => {
const branchName: string = footPrint.branch;

gitgraph.branch(footPrint.branch).commit({
hash: footPrint.commit?.hash ?? '',
subject: footPrint.commit?.message ?? index === 0 ? '' : `Checkout to ${footPrint.branch}`,
subject: index === 0 ? branchName : footPrint.commit?.message ?? `Checkout to ${footPrint.branch}`,
onClick: () => clickOnCommitHandler(footPrint.commit.hash),
onMessageClick: () => clickOnCommitHandler(footPrint.commit.hash),
style: {
Expand Down
10 changes: 10 additions & 0 deletions client/src/components/Menu/Help.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ const Help = () => {
<br />
Harmony keeps track of the branches and commits you create allowing you to go back to a specific commit.
<video width="100%" src="https://user-images.githubusercontent.com/78874117/194714002-f6ec20c5-c7cc-4144-85e1-0bdb65097b7d.mov" controls autoPlay></video>
<br />
Click on the commits with the Hash (not the Checkout commits) to visit that particular commit.
<br />
<br />
<br />
<strong>Harmony also has a basic support for Folders</strong> (does not support nested folders yet)
<video width="100%" src="https://user-images.githubusercontent.com/78874117/194757713-771d1df7-3272-497b-9973-2e253da13e20.mp4" controls autoPlay></video>
<br />
Create one by simply creating a new file with this format: <strong>"DIRECTORY_NAME/FILE_NAME"</strong>.
<br />
{(action === HELP || open) && (
<Button
sx={{
Expand Down
Binary file modified client/src/img/desktop.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/src/img/desktopp.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions client/src/utils/goFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,12 @@ export const virtualCommitWrapper = (commitMsg: string) => {

// @ts-ignore
export const goToCommitWrapper = (hash: string) => goToCommit(hash);

export const exploreDirectoryWrapper = (filename: string) => {
// @ts-ignore
const filepath = `./${filename}/` + exploreDirectory(filename);
return filepath.split(' ');
};

// @ts-ignore
export const isDirectoryWrapper = (filename: string) => isDirectory(filename);
2 changes: 2 additions & 0 deletions nova/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ func main() {
js.Global().Set("getVirtualFiles", mapping.GetVirtualFiles())
js.Global().Set("goToBranch", mapping.GoToBranch())
js.Global().Set("goToCommit", mapping.GoToCommit())
js.Global().Set("exploreDirectory", mapping.ExploreDirectory())
js.Global().Set("isDirectory", mapping.IsDirectory())
<-ch
}
15 changes: 15 additions & 0 deletions nova/mapping/mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,18 @@ func GoToCommit() js.Func {
return commitHash
})
}

func ExploreDirectory() js.Func {
return js.FuncOf(func(this js.Value, args []js.Value) interface{} {
filename := args[0].String()
filenames := novaStore.ExploreDirectory(store, texts.CurrentDirectory, filename)
return strings.Join(filenames, " ")
})
}

func IsDirectory() js.Func {
return js.FuncOf(func(this js.Value, args []js.Value) interface{} {
filename := args[0].String()
return novaStore.IsDirectory(store, texts.CurrentDirectory, filename)
})
}
36 changes: 36 additions & 0 deletions nova/virtual/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,42 @@ func listFiles(store billy.Filesystem, dir string) []string {
return fileInfos
}

func isDirectory(store billy.Filesystem, dir string, filename string) bool {
files, err := store.ReadDir(dir)

if err != nil {
log.Println(err)
return false
}

for _, file := range files {
if file.Name() == filename {
if file.IsDir() {
return true
}
}
}

return false
}

func getDirectoryFiles(store billy.Filesystem, dir string, filename string) []string {
files, err := store.ReadDir(dir)

if err != nil {
log.Println(err)
return nil
}
for _, file := range files {
if file.Name() == filename {
if file.IsDir() {
return listFiles(store, file.Name())
}
}
}
return nil
}

func openFile(store billy.Filesystem, fileName string) (billy.Filesystem, billy.File) {
newFile, err := store.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
Expand Down
10 changes: 10 additions & 0 deletions nova/virtual/virtualSystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ type StoreInterface interface {
Screenshot(store billy.Filesystem, wt *git.Worktree, msg string) string
GotoBranch(repo *git.Repository, branchName string) error
GoToCommit(repo *git.Repository, commitHash string) error
IsDirectory(store billy.Filesystem, dir string, filename string) bool
ExploreDirectory(store billy.Filesystem, dir string, filename string) []string
}
type NovaStore struct {
Watcher map[string]string
Expand All @@ -44,6 +46,14 @@ func (ns *NovaStore) GetFiles(store billy.Filesystem, dir string) []string {
return listFiles(store, dir)
}

func (ns *NovaStore) ExploreDirectory(store billy.Filesystem, dir string, filename string) []string {
return getDirectoryFiles(store, dir, filename)
}

func (ns *NovaStore) IsDirectory(store billy.Filesystem, dir string, filename string) bool {
return isDirectory(store, dir, filename)
}

func (ns *NovaStore) OpenFile(store billy.Filesystem, fileName string) billy.File {
fileGotCreated, file := openFile(store, fileName)
if fileGotCreated != nil {
Expand Down

1 comment on commit 69a334b

@vercel
Copy link

@vercel vercel bot commented on 69a334b Oct 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

harmonyland – ./

harmonyland-git-master-thomscoder.vercel.app
harmonyland.vercel.app
harmonyland-thomscoder.vercel.app

Please sign in to comment.