feat: write user and project to disk

does not contain documents or groups
This commit is contained in:
Joshua Shoemaker 2023-03-26 20:08:23 -05:00
parent 01529b731c
commit d9916b967a
24 changed files with 703 additions and 206 deletions

View File

@ -2,6 +2,10 @@ package app
import ( import (
"context" "context"
"fmt"
document "textualize/core/Document"
session "textualize/core/Session"
storage "textualize/storage/Local"
) )
type App struct { type App struct {
@ -20,25 +24,12 @@ func GetInstance() *App {
func (a *App) Startup(ctx context.Context) { func (a *App) Startup(ctx context.Context) {
a.Context = ctx a.Context = ctx
} localUserData := storage.ReadLocalUserData()
session.InitializeModule(session.Session{
User: session.User(localUserData),
})
type Language struct { document.InitizeModule()
DisplayName string
ProcessCode string
TranslateCode string
}
func GetSuppportedLanguages() []Language { fmt.Println(localUserData)
return []Language{
{
DisplayName: "English",
ProcessCode: "eng",
TranslateCode: "en",
},
{
DisplayName: "Hebrew",
ProcessCode: "heb",
TranslateCode: "he",
},
}
} }

22
core/Consts/Consts.go Normal file
View File

@ -0,0 +1,22 @@
package consts
type Language struct {
DisplayName string
ProcessCode string
TranslateCode string
}
func GetSuppportedLanguages() []Language {
return []Language{
{
DisplayName: "English",
ProcessCode: "eng",
TranslateCode: "en",
},
{
DisplayName: "Hebrew",
ProcessCode: "heb",
TranslateCode: "he",
},
}
}

View File

@ -1,7 +1,7 @@
package document package document
import ( import (
app "textualize/core/App" consts "textualize/core/Consts"
) )
type Entity struct { type Entity struct {
@ -11,7 +11,7 @@ type Entity struct {
Path string Path string
ProjectId string ProjectId string
Areas []Area Areas []Area
DefaultLanguage app.Language DefaultLanguage consts.Language
} }
type Area struct { type Area struct {
@ -21,7 +21,7 @@ type Area struct {
StartY int StartY int
EndX int EndX int
EndY int EndY int
Language app.Language Language consts.Language
Order int Order int
} }

View File

@ -5,6 +5,7 @@ type Group struct {
ParentId string ParentId string
ProjectId string ProjectId string
Name string Name string
Order int
} }
type GroupCollection struct { type GroupCollection struct {
@ -26,3 +27,14 @@ func GetGroupCollection() *GroupCollection {
func (collection *GroupCollection) AddDocumentGroup(group Group) { func (collection *GroupCollection) AddDocumentGroup(group Group) {
collection.Groups = append(collection.Groups, group) collection.Groups = append(collection.Groups, group)
} }
func (collection *GroupCollection) GetGroupById(groupId string) *Group {
var foundGroup *Group
for index, g := range collection.Groups {
if g.Id == groupId {
foundGroup = &collection.Groups[index]
}
}
return foundGroup
}

View File

@ -30,7 +30,7 @@ type ProcessedArea struct {
Id string Id string
DocumentId string DocumentId string
FullText string FullText string
Order int // TODO: make reorder feature Order int
Lines []ProcessedLine Lines []ProcessedLine
} }

View File

@ -1,7 +1,7 @@
package session package session
import ( import (
app "textualize/core/App" consts "textualize/core/Consts"
) )
type Project struct { type Project struct {
@ -12,7 +12,7 @@ type Project struct {
} }
type ProjectSettings struct { type ProjectSettings struct {
DefaultProcessLanguage app.Language DefaultProcessLanguage consts.Language
DefaultTranslateTargetLanguage app.Language DefaultTranslateTargetLanguage consts.Language
IsHosted bool IsHosted bool
} }

View File

@ -6,13 +6,19 @@ import { Fragment, useState } from 'react'
import { useNavigation } from '../../context/Navigation/provider' import { useNavigation } from '../../context/Navigation/provider'
import { mainPages } from '../../context/Navigation/types' import { mainPages } from '../../context/Navigation/types'
import { useProject } from '../../context/Project/provider' import { useProject } from '../../context/Project/provider'
import { GetAllLocalProjects } from '../../wailsjs/wailsjs/go/ipc/Channel'
import { ipc } from '../../wailsjs/wailsjs/go/models'
import NewProjectModal from './NewProjectModal' import NewProjectModal from './NewProjectModal'
import ProjectListModal from './ProjectListModal'
const MainProject = () => { const MainProject = () => {
const [isNewProjectModalOpen, setIsNewProjectModalOpen] = useState(false) const [isNewProjectModalOpen, setIsNewProjectModalOpen] = useState(false)
const [isProjectListModal, setIsProjectListModal] = useState(false)
const [canPopoverBeOpen, setCanPopoverBeOpen] = useState(true) const [canPopoverBeOpen, setCanPopoverBeOpen] = useState(true)
const { createNewProject } = useProject()
const [avalibleProjects, setAvalibleProjects] = useState<ipc.Project[]>([])
const { createNewProject, requestSelectProjectByName } = useProject()
const { setSelectedMainPage } = useNavigation() const { setSelectedMainPage } = useNavigation()
const buttonOptions = [ const buttonOptions = [
@ -31,6 +37,11 @@ const MainProject = () => {
icon: <FolderOpenIcon className='w-10 h-9 stroke-slate-600' />, icon: <FolderOpenIcon className='w-10 h-9 stroke-slate-600' />,
onClick: () => { onClick: () => {
setCanPopoverBeOpen(false) setCanPopoverBeOpen(false)
GetAllLocalProjects().then(response => {
console.log(response)
setAvalibleProjects(response)
setIsProjectListModal(true)
})
}, },
}, },
{ {
@ -50,10 +61,20 @@ const MainProject = () => {
setSelectedMainPage(mainPages.WORKSPACE) setSelectedMainPage(mainPages.WORKSPACE)
} }
const onSelectProjectHandler = async (name: string) => {
const successfulResponse = await requestSelectProjectByName(name)
setIsProjectListModal(false)
setCanPopoverBeOpen(true)
if (successfulResponse) setSelectedMainPage(mainPages.WORKSPACE)
}
return <main className=" text-gray-100 h-screen overflow-y-scroll"> return <main className=" text-gray-100 h-screen overflow-y-scroll">
{isNewProjectModalOpen ? <NewProjectModal onCreateNewProjectHandler={onCreateNewProjectHandler} /> : ''} {isNewProjectModalOpen ? <NewProjectModal onCreateNewProjectHandler={onCreateNewProjectHandler} /> : ''}
{isProjectListModal ? <ProjectListModal onSelectProjectHandler={onSelectProjectHandler} projects={avalibleProjects} /> : '' }
<div className="py-20 px-6 sm:px-6 sm:py-32 lg:px-8"> <div className="py-20 px-6 sm:px-6 sm:py-32 lg:px-8">
<div className="mx-auto max-w-2xl text-center"> <div className="mx-auto max-w-2xl text-center">

View File

@ -0,0 +1,49 @@
import { ipc } from '../../wailsjs/wailsjs/go/models'
type Props = { projects: ipc.Project[], onSelectProjectHandler: (projectName: string) => void }
const ProjectListModal = (props: Props) => {
return (
<div className=" p-8 absolute top-2/4 -translate-y-1/2 left-2/4 -translate-x-1/2 z-50 bg-white shadow sm:rounded-lg">
<div className="px-4 py-5 sm:p-6">
<h3 className="text-lg font-medium leading-6 text-gray-900">Select your Existing Project</h3>
<div className="mt-6 flow-root">
<ul role="list" className="-my-5 divide-y divide-gray-200">
{props.projects.map((p) => (
<li key={p.id} className="py-4">
<div className="flex items-center space-x-4">
<div className="flex-shrink-0">
{/* <img className="h-8 w-8 rounded-full" src={p.imageUrl} alt="" /> */}
</div>
<div className="min-w-0 flex-1">
<h2 className="truncate text-xl text-gray-900 font-bold">{p.name}</h2>
<p className="truncate text-xs text-gray-400">{'id: ' + p.id}</p>
</div>
<div>
<a
href="#"
onClick={() => props.onSelectProjectHandler(p.name)}
className="inline-flex items-center rounded-full bg-white px-2.5 py-1 text-xs font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50"
>
Open
</a>
</div>
</div>
</li>
))}
</ul>
</div>
<div className="mt-6">
{/* <a
href="#"
className="flex w-full items-center justify-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0"
>
View all
</a> */}
</div>
</div>
</div>
)
}
export default ProjectListModal

View File

@ -19,6 +19,10 @@ const Search = () => {
name: 'Document Workspace', name: 'Document Workspace',
onClick: () => { setSelectedMainPage(mainPages.WORKSPACE) } onClick: () => { setSelectedMainPage(mainPages.WORKSPACE) }
}, },
{
name: 'Change Project',
onClick: () => { setSelectedMainPage(mainPages.SELECTPROJECT) }
},
{ {
name: 'Sign Out', name: 'Sign Out',
onClick: () => { setSelectedMainPage(mainPages.SELECTPROJECT) } onClick: () => { setSelectedMainPage(mainPages.SELECTPROJECT) }

View File

@ -66,7 +66,8 @@ const AreaLineItem = (props: { area: SidebarArea, documentId: string, index: num
} }
const onAreaDropEnd = (areaId: string) => { const onAreaDropEnd = (areaId: string) => {
const areaDroppedOn = getAreaById(areaId) const areaDroppedOn = getAreaById(dragOverAreaId)
console.log(areaDroppedOn)
if (!areaDroppedOn) return if (!areaDroppedOn) return
requestChangeAreaOrder(areaId, areaDroppedOn.order) requestChangeAreaOrder(areaId, areaDroppedOn.order)
setDragOverAreaId('') setDragOverAreaId('')

View File

@ -1,7 +1,7 @@
'use client' 'use client'
import { DocumentPlusIcon, PlusIcon, XMarkIcon } from '@heroicons/react/24/outline' import { DocumentPlusIcon, PlusIcon, XMarkIcon } from '@heroicons/react/24/outline'
import React, { useRef } from 'react' import React, { useRef, useState } from 'react'
import { useProject } from '../../../context/Project/provider' import { useProject } from '../../../context/Project/provider'
import classNames from '../../../utils/classNames' import classNames from '../../../utils/classNames'
import onEnterHandler from '../../../utils/onEnterHandler' import onEnterHandler from '../../../utils/onEnterHandler'
@ -14,9 +14,11 @@ import { SidebarGroup } from './types'
const GroupLineItem = (props: { group: SidebarGroup }) => { const GroupLineItem = (props: { group: SidebarGroup }) => {
const { const {
requestAddDocument requestAddDocument,
requestChangeGroupOrder,
getGroupById,
} = useProject() } = useProject()
const { const {
selectedGroupId, selectedGroupId,
isAddNewDocumentInputShowing, isAddNewDocumentInputShowing,
@ -28,6 +30,8 @@ const GroupLineItem = (props: { group: SidebarGroup }) => {
const addDocumentTextInput = useRef<HTMLInputElement>(null) const addDocumentTextInput = useRef<HTMLInputElement>(null)
const [dragOverGroupId, setDragOverGroupId] = useState('')
const onConfirmAddDocumentClickHandler = async (groupId: string) => { const onConfirmAddDocumentClickHandler = async (groupId: string) => {
const documentName = addDocumentTextInput.current?.value const documentName = addDocumentTextInput.current?.value
if (!documentName) return if (!documentName) return
@ -50,6 +54,22 @@ const GroupLineItem = (props: { group: SidebarGroup }) => {
setIsAddNewGroupInputShowing(false) setIsAddNewGroupInputShowing(false)
} }
const onGroupDragOver = (groupId: string) => {
setDragOverGroupId(groupId)
}
const onGroupDragStart = (groupId: string) => {
setSelectedGroupId(groupId)
}
const onGroupDropEnd = (groupId: string) => {
const areaDroppedOn = getGroupById(groupId)
console.log('areaDroppedOn', areaDroppedOn)
if (!areaDroppedOn) return
const response = requestChangeGroupOrder(groupId, areaDroppedOn.order)
setDragOverGroupId('')
}
const renderAddNewDocument = (groupId: string) => { const renderAddNewDocument = (groupId: string) => {
return isAddNewDocumentInputShowing && selectedGroupId === groupId return isAddNewDocumentInputShowing && selectedGroupId === groupId
? <div className="flex rounded-md shadow-sm"> ? <div className="flex rounded-md shadow-sm">
@ -83,7 +103,8 @@ const GroupLineItem = (props: { group: SidebarGroup }) => {
<PlusIcon className="h-7 w-5" aria-hidden="true" /> <PlusIcon className="h-7 w-5" aria-hidden="true" />
</button> </button>
</div> </div>
: <a :
<a
role='button' role='button'
className={classNames( className={classNames(
'text-gray-300 hover:bg-gray-700 hover:text-white', 'text-gray-300 hover:bg-gray-700 hover:text-white',
@ -98,156 +119,160 @@ const GroupLineItem = (props: { group: SidebarGroup }) => {
} }
return (<details key={props.group.name} open={props.group.id === selectedGroupId}> return (<details key={props.group.name} open={props.group.id === selectedGroupId}>
<summary className={classNames( <summary
props.group.id === selectedGroupId draggable
? 'bg-gray-900 text-white' onDragOver={() => onGroupDragOver(props.group.id)}
: 'text-gray-300 hover:bg-gray-700 hover:text-white', onDragEnd={() => onGroupDropEnd(props.group.id)}
'group items-center px-2 py-2 text-base font-medium rounded-t-md' className={classNames(
)}> 'group items-center px-2 py-2 text-base font-medium rounded-t-md',
<a role='button'>{props.group.name}</a> selectedGroupId === props.group.id ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white',
</summary> (dragOverGroupId === props.group.id) && props.group.id ? 'bg-gray-300 text-gray-700' : '',
<ul> )}
{props.group.documents.map((d, index) => ( >
<DocumentLineItem key={d.id} document={d} index={index} groupId={props.group.id} /> <a role='button'>{props.group.name}</a>
// <li className='p-0 m-0' key={d.id}> </summary>
// {!d.areas.length <ul>
// ? {props.group.documents.map((d, index) => (
// <div <DocumentLineItem key={d.id} document={d} index={index} groupId={props.group.id} />
// onClick={() => onDocumentClickHandler(d.id)} // <li className='p-0 m-0' key={d.id}>
// onDoubleClick={() => onDocumentDoubleClickHandler(d.id)} // {!d.areas.length
// className={classNames( // ?
// d.id === selectedDocumentId // <div
// ? 'bg-gray-900 text-white' // onClick={() => onDocumentClickHandler(d.id)}
// : 'text-gray-300 hover:bg-gray-700 hover:text-white', // onDoubleClick={() => onDocumentDoubleClickHandler(d.id)}
// 'group items-center py-2 text-base font-medium rounded-b-md pl-10', // className={classNames(
// index !== 0 ? 'rounded-t-md' : '', // d.id === selectedDocumentId
// )}> // ? 'bg-gray-900 text-white'
// {selectedDocumentId === d.id && isEditDocumentNameInputShowing // : 'text-gray-300 hover:bg-gray-700 hover:text-white',
// ? <input // 'group items-center py-2 text-base font-medium rounded-b-md pl-10',
// type="text" // index !== 0 ? 'rounded-t-md' : '',
// name="documentName" // )}>
// id="documentName" // {selectedDocumentId === d.id && isEditDocumentNameInputShowing
// autoFocus // ? <input
// className="h-8 w-[calc(100%-18px)] text-white placeholder-gray-400 bg-gray-900 bg-opacity-5 inline-block rounded-none rounded-l-md border-late-700 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" // type="text"
// defaultValue={d.name} // name="documentName"
// onBlur={onDocumentInputBlur} // id="documentName"
// onKeyDown={(event) => { // autoFocus
// onEnterHandler(event, // className="h-8 w-[calc(100%-18px)] text-white placeholder-gray-400 bg-gray-900 bg-opacity-5 inline-block rounded-none rounded-l-md border-late-700 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
// () => onConfirmDocumentNameChangeHandler(event.currentTarget.value)) // defaultValue={d.name}
// }} // onBlur={onDocumentInputBlur}
// ref={editDocumentNameTextInput} // onKeyDown={(event) => {
// /> // onEnterHandler(event,
// : <a // () => onConfirmDocumentNameChangeHandler(event.currentTarget.value))
// role='button' // }}
// className={classNames( // ref={editDocumentNameTextInput}
// d.id === selectedDocumentId // />
// ? 'bg-gray-900 text-white' // : <a
// : 'text-gray-300 hover:bg-gray-700 hover:text-white', // role='button'
// 'text-left font-medium text-sm rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 ' // className={classNames(
// )} // d.id === selectedDocumentId
// > // ? 'bg-gray-900 text-white'
// {d.name} // : 'text-gray-300 hover:bg-gray-700 hover:text-white',
// </a> // 'text-left font-medium text-sm rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 '
// } // )}
// </div> // >
// : <details> // {d.name}
// <summary // </a>
// onClick={() => onDocumentClickHandler(d.id)} // }
// onDoubleClick={() => onDocumentDoubleClickHandler(d.id)} // </div>
// className={classNames( // : <details>
// d.id === selectedDocumentId // <summary
// ? 'bg-gray-900 text-white' // onClick={() => onDocumentClickHandler(d.id)}
// : 'text-gray-300 hover:bg-gray-700 hover:text-white', // onDoubleClick={() => onDocumentDoubleClickHandler(d.id)}
// 'group items-center py-2 text-base font-medium rounded-b-md pl-6', // className={classNames(
// index !== 0 ? 'rounded-t-md' : '', // d.id === selectedDocumentId
// ? 'bg-gray-900 text-white'
// : 'text-gray-300 hover:bg-gray-700 hover:text-white',
// 'group items-center py-2 text-base font-medium rounded-b-md pl-6',
// index !== 0 ? 'rounded-t-md' : '',
// )}> // )}>
// {selectedDocumentId === d.id && isEditDocumentNameInputShowing // {selectedDocumentId === d.id && isEditDocumentNameInputShowing
// ? <input // ? <input
// type="text" // type="text"
// name="documentName" // name="documentName"
// id="documentName" // id="documentName"
// autoFocus // autoFocus
// className="h-8 w-[calc(100%-18px)] text-white placeholder-gray-400 bg-gray-900 bg-opacity-5 inline-block rounded-none rounded-l-md border-late-700 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" // className="h-8 w-[calc(100%-18px)] text-white placeholder-gray-400 bg-gray-900 bg-opacity-5 inline-block rounded-none rounded-l-md border-late-700 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
// defaultValue={d.name} // defaultValue={d.name}
// onBlur={onDocumentInputBlur} // onBlur={onDocumentInputBlur}
// onKeyDown={(event) => { // onKeyDown={(event) => {
// onEnterHandler(event, // onEnterHandler(event,
// () => onConfirmDocumentNameChangeHandler(event.currentTarget.value)) // () => onConfirmDocumentNameChangeHandler(event.currentTarget.value))
// }} // }}
// ref={editDocumentNameTextInput} // ref={editDocumentNameTextInput}
// /> // />
// : <a // : <a
// role='button' // role='button'
// className={classNames( // className={classNames(
// d.id === selectedDocumentId // d.id === selectedDocumentId
// ? 'bg-gray-900 text-white' // ? 'bg-gray-900 text-white'
// : 'text-gray-300 hover:bg-gray-700 hover:text-white', // : 'text-gray-300 hover:bg-gray-700 hover:text-white',
// 'text-left font-medium text-sm rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 ' // 'text-left font-medium text-sm rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 '
// )} // )}
// > // >
// {d.name} // {d.name}
// </a> // </a>
// } // }
// </summary> // </summary>
// <ul> // <ul>
// {d.areas.map((a, index) => ( // {d.areas.map((a, index) => (
// <li key={a.id}> // <li key={a.id}>
// {selectedAreaId === a.id && isEditAreaNameInputShowing // {selectedAreaId === a.id && isEditAreaNameInputShowing
// ? <input // ? <input
// type="text" // type="text"
// name="areaName" // name="areaName"
// id="areaName" // id="areaName"
// autoFocus // autoFocus
// className="h-8 text-white placeholder-gray-400 bg-gray-900 bg-opacity-5 block w-full rounded-none rounded-l-md border-late-700 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" // className="h-8 text-white placeholder-gray-400 bg-gray-900 bg-opacity-5 block w-full rounded-none rounded-l-md border-late-700 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
// placeholder={a.name || `Area ${index}`} // placeholder={a.name || `Area ${index}`}
// onBlur={onAreaInputBlur} // onBlur={onAreaInputBlur}
// onKeyDown={(event) => { // onKeyDown={(event) => {
// onEnterHandler(event, // onEnterHandler(event,
// () => onConfirmAreaNameChangeHandler({ areaId: a.id, areaName: event.currentTarget.value })) // () => onConfirmAreaNameChangeHandler({ areaId: a.id, areaName: event.currentTarget.value }))
// }} // }}
// ref={editAreaNameTextInput} // ref={editAreaNameTextInput}
// /> // />
// : <div // : <div
// draggable // draggable
// onDragOver={() => onAreaDragOver(a.id)} // onDragOver={() => onAreaDragOver(a.id)}
// onDragStart={() => onAreaDragStart(a.id)} // onDragStart={() => onAreaDragStart(a.id)}
// onDragEnd={() => onAreaDropEnd(a.id)} // onDragEnd={() => onAreaDropEnd(a.id)}
// className={classNames('flex justify-between items-center cursor-pointer', // className={classNames('flex justify-between items-center cursor-pointer',
// selectedAreaId === a.id ? 'bg-indigo-500 text-gray-200' : 'text-gray-300 hover:bg-gray-700 hover:text-white', // selectedAreaId === a.id ? 'bg-indigo-500 text-gray-200' : 'text-gray-300 hover:bg-gray-700 hover:text-white',
// dragOverAreaId === a.id ? 'bg-gray-300 text-gray-700' : '', // dragOverAreaId === a.id ? 'bg-gray-300 text-gray-700' : '',
// selectedAreaId === a.id && dragOverAreaId === a.id ? 'bg-indigo-300' : '', // selectedAreaId === a.id && dragOverAreaId === a.id ? 'bg-indigo-300' : '',
// )}> // )}>
// <a // <a
// role='button' // role='button'
// onClick={() => onAreaClick(a.id)} // onClick={() => onAreaClick(a.id)}
// onDoubleClick={() => onAreaDoubleClick(a.id)} // onDoubleClick={() => onAreaDoubleClick(a.id)}
// className={classNames('group w-full pr-2 py-2 text-left font-medium pl-8 text-xs', // className={classNames('group w-full pr-2 py-2 text-left font-medium pl-8 text-xs',
// 'rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 py-2 select-none', // 'rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 py-2 select-none',
// )}> // )}>
// {a.name || `Area ${a.order}`} // {a.name || `Area ${a.order}`}
// </a> // </a>
// <ArrowPathIcon // <ArrowPathIcon
// className='w-6 h-5 mr-2 text-white hover:bg-white hover:text-gray-700 rounded-full p-0.5' // className='w-6 h-5 mr-2 text-white hover:bg-white hover:text-gray-700 rounded-full p-0.5'
// aria-hidden="true" // aria-hidden="true"
// onClick={() => console.log('refresh')} // onClick={() => console.log('refresh')}
// /> // />
// <XMarkIcon // <XMarkIcon
// className='w-6 h-5 mr-2 text-white hover:bg-red-400 hover:text-gray-100 rounded-full p-0.5' // className='w-6 h-5 mr-2 text-white hover:bg-red-400 hover:text-gray-100 rounded-full p-0.5'
// onClick={() => handleAreaDeleteButtonClick(a.id)} /> // onClick={() => handleAreaDeleteButtonClick(a.id)} />
// </div> // </div>
// } // }
// </li> // </li>
// ))} // ))}
// </ul> // </ul>
// </details> // </details>
// } // }
// </li> // </li>
))} ))}
{renderAddNewDocument(props.group.id)} {renderAddNewDocument(props.group.id)}
</ul> </ul>
</details> </details>
) )
} }

View File

@ -26,6 +26,9 @@ const makeDefaultProject = (): ProjectContextType => ({
requestChooseUserAvatar: () => Promise.resolve(''), requestChooseUserAvatar: () => Promise.resolve(''),
requestUpdateDocument: ({}) => Promise.resolve(new ipc.Document), requestUpdateDocument: ({}) => Promise.resolve(new ipc.Document),
requestChangeAreaOrder: (areaId: string, newOrder: number) => Promise.resolve(new ipc.Document()), requestChangeAreaOrder: (areaId: string, newOrder: number) => Promise.resolve(new ipc.Document()),
requestChangeGroupOrder: (groupId: string, newOrder: number) => Promise.resolve(new ipc.Group()),
getGroupById: (groupId) => undefined,
requestSelectProjectByName: (projectName) => Promise.resolve(false),
}) })
export default makeDefaultProject export default makeDefaultProject

View File

@ -10,6 +10,9 @@ import {
RequestUpdateDocument, RequestUpdateDocument,
RequestChangeAreaOrder, RequestChangeAreaOrder,
RequestDeleteAreaById, RequestDeleteAreaById,
RequestChangeGroupOrder,
GetProjectByName,
RequestChangeSessionProjectByName,
} from '../../wailsjs/wailsjs/go/ipc/Channel' } from '../../wailsjs/wailsjs/go/ipc/Channel'
import { ipc } from '../../wailsjs/wailsjs/go/models' import { ipc } from '../../wailsjs/wailsjs/go/models'
import { AddAreaProps, AreaProps, ProjectContextType, ProjectProps, UpdateDocumentRequest, UserProps } from './types' import { AddAreaProps, AreaProps, ProjectContextType, ProjectProps, UpdateDocumentRequest, UserProps } from './types'
@ -21,6 +24,8 @@ export function useProject() {
return useContext(ProjectContext) return useContext(ProjectContext)
} }
let attempts = 0
type Props = { children: ReactNode, projectProps: ProjectProps } type Props = { children: ReactNode, projectProps: ProjectProps }
export function ProjectProvider({ children, projectProps }: Props) { export function ProjectProvider({ children, projectProps }: Props) {
const [documents, setDocuments] = useState<ipc.Document[]>(projectProps.documents) const [documents, setDocuments] = useState<ipc.Document[]>(projectProps.documents)
@ -110,6 +115,7 @@ export function ProjectProvider({ children, projectProps }: Props) {
const updateSession = async () => { const updateSession = async () => {
GetCurrentSession().then(response => { GetCurrentSession().then(response => {
if (response) setCurrentSession(response) if (response) setCurrentSession(response)
console.log(response)
Promise.resolve(response) Promise.resolve(response)
}) })
} }
@ -143,10 +149,34 @@ export function ProjectProvider({ children, projectProps }: Props) {
return response return response
} }
const getGroupById = (groupId: string): ipc.Group | undefined => (
groups.find(g => g.id === groupId)
)
const requestChangeGroupOrder = async (groupId: string, newOrder: number) => {
const response = await RequestChangeGroupOrder(groupId, newOrder)
await updateDocuments()
return response
}
const requestSelectProjectByName = async (name: string) => {
const successfulResponse = await RequestChangeSessionProjectByName(name)
await updateSession()
return successfulResponse
}
useEffect(() => { useEffect(() => {
if (!documents.length && !groups.length) updateDocuments() if (!documents.length && !groups.length) updateDocuments()
}, [documents.length, groups.length]) }, [documents.length, groups.length])
useEffect(() => {
if ((!currentSession?.user?.localId || !currentSession?.user?.id)) {
updateSession()
attempts++
}
}, [currentSession?.user?.localId, currentSession?.user?.id])
const value = { const value = {
id: '', id: '',
documents, documents,
@ -172,6 +202,9 @@ export function ProjectProvider({ children, projectProps }: Props) {
requestChooseUserAvatar, requestChooseUserAvatar,
requestUpdateDocument, requestUpdateDocument,
requestChangeAreaOrder, requestChangeAreaOrder,
requestChangeGroupOrder,
getGroupById,
requestSelectProjectByName,
} }
return <ProjectContext.Provider value={value}> return <ProjectContext.Provider value={value}>

View File

@ -58,4 +58,7 @@ export type ProjectContextType = {
requestChooseUserAvatar: () => Promise<string> requestChooseUserAvatar: () => Promise<string>
requestUpdateDocument: (request: UpdateDocumentRequest) => Promise<ipc.Document> requestUpdateDocument: (request: UpdateDocumentRequest) => Promise<ipc.Document>
requestChangeAreaOrder: (areaId: string, newOrder: number) => Promise<ipc.Document> requestChangeAreaOrder: (areaId: string, newOrder: number) => Promise<ipc.Document>
requestChangeGroupOrder: (groupId: string, newOrder: number) => Promise<ipc.Group>
getGroupById: (groupId: string) => ipc.Group | undefined
requestSelectProjectByName: (projectName: string) => Promise<boolean>
} & ProjectProps } & ProjectProps

View File

@ -1,4 +1,5 @@
import { NextPage } from 'next' import { NextPage } from 'next'
import { useEffect, useState } from 'react'
import MainHead from '../components/head' import MainHead from '../components/head'
import MainProject from '../components/project/Main' import MainProject from '../components/project/Main'
import User from '../components/settings/User' import User from '../components/settings/User'
@ -9,7 +10,6 @@ import { mainPages } from '../context/Navigation/types'
import { useProject } from '../context/Project/provider' import { useProject } from '../context/Project/provider'
const Home: NextPage = () => { const Home: NextPage = () => {
const { currentSession } = useProject() const { currentSession } = useProject()
const { selectedMainPage } = useNavigation() const { selectedMainPage } = useNavigation()

View File

@ -4,6 +4,8 @@ import {ipc} from '../models';
export function CreateNewProject(arg1:string):Promise<ipc.Session>; export function CreateNewProject(arg1:string):Promise<ipc.Session>;
export function GetAllLocalProjects():Promise<Array<ipc.Project>>;
export function GetAreaById(arg1:string):Promise<ipc.Area>; export function GetAreaById(arg1:string):Promise<ipc.Area>;
export function GetCurrentSession():Promise<ipc.Session>; export function GetCurrentSession():Promise<ipc.Session>;
@ -16,6 +18,8 @@ export function GetDocuments():Promise<ipc.GetDocumentsResponse>;
export function GetProcessedAreasByDocumentId(arg1:string):Promise<Array<ipc.ProcessedArea>>; export function GetProcessedAreasByDocumentId(arg1:string):Promise<Array<ipc.ProcessedArea>>;
export function GetProjectByName(arg1:string):Promise<ipc.Project>;
export function GetSuppportedLanguages():Promise<Array<ipc.Language>>; export function GetSuppportedLanguages():Promise<Array<ipc.Language>>;
export function GetUserMarkdownByDocumentId(arg1:string):Promise<ipc.UserMarkdown>; export function GetUserMarkdownByDocumentId(arg1:string):Promise<ipc.UserMarkdown>;
@ -30,6 +34,10 @@ export function RequestAddProcessedArea(arg1:ipc.ProcessedArea):Promise<ipc.Proc
export function RequestChangeAreaOrder(arg1:string,arg2:number):Promise<ipc.Document>; export function RequestChangeAreaOrder(arg1:string,arg2:number):Promise<ipc.Document>;
export function RequestChangeGroupOrder(arg1:string,arg2:number):Promise<ipc.Group>;
export function RequestChangeSessionProjectByName(arg1:string):Promise<boolean>;
export function RequestChooseUserAvatar():Promise<string>; export function RequestChooseUserAvatar():Promise<string>;
export function RequestDeleteAreaById(arg1:string):Promise<boolean>; export function RequestDeleteAreaById(arg1:string):Promise<boolean>;

View File

@ -6,6 +6,10 @@ export function CreateNewProject(arg1) {
return window['go']['ipc']['Channel']['CreateNewProject'](arg1); return window['go']['ipc']['Channel']['CreateNewProject'](arg1);
} }
export function GetAllLocalProjects() {
return window['go']['ipc']['Channel']['GetAllLocalProjects']();
}
export function GetAreaById(arg1) { export function GetAreaById(arg1) {
return window['go']['ipc']['Channel']['GetAreaById'](arg1); return window['go']['ipc']['Channel']['GetAreaById'](arg1);
} }
@ -30,6 +34,10 @@ export function GetProcessedAreasByDocumentId(arg1) {
return window['go']['ipc']['Channel']['GetProcessedAreasByDocumentId'](arg1); return window['go']['ipc']['Channel']['GetProcessedAreasByDocumentId'](arg1);
} }
export function GetProjectByName(arg1) {
return window['go']['ipc']['Channel']['GetProjectByName'](arg1);
}
export function GetSuppportedLanguages() { export function GetSuppportedLanguages() {
return window['go']['ipc']['Channel']['GetSuppportedLanguages'](); return window['go']['ipc']['Channel']['GetSuppportedLanguages']();
} }
@ -58,6 +66,14 @@ export function RequestChangeAreaOrder(arg1, arg2) {
return window['go']['ipc']['Channel']['RequestChangeAreaOrder'](arg1, arg2); return window['go']['ipc']['Channel']['RequestChangeAreaOrder'](arg1, arg2);
} }
export function RequestChangeGroupOrder(arg1, arg2) {
return window['go']['ipc']['Channel']['RequestChangeGroupOrder'](arg1, arg2);
}
export function RequestChangeSessionProjectByName(arg1) {
return window['go']['ipc']['Channel']['RequestChangeSessionProjectByName'](arg1);
}
export function RequestChooseUserAvatar() { export function RequestChooseUserAvatar() {
return window['go']['ipc']['Channel']['RequestChooseUserAvatar'](); return window['go']['ipc']['Channel']['RequestChooseUserAvatar']();
} }

View File

@ -107,6 +107,7 @@ export namespace ipc {
parentId: string; parentId: string;
projectId: string; projectId: string;
name: string; name: string;
order: number;
static createFrom(source: any = {}) { static createFrom(source: any = {}) {
return new Group(source); return new Group(source);
@ -118,6 +119,7 @@ export namespace ipc {
this.parentId = source["parentId"]; this.parentId = source["parentId"];
this.projectId = source["projectId"]; this.projectId = source["projectId"];
this.name = source["name"]; this.name = source["name"];
this.order = source["order"];
} }
} }
export class GetDocumentsResponse { export class GetDocumentsResponse {
@ -381,7 +383,7 @@ export namespace ipc {
export class ProjectSettings { export class ProjectSettings {
defaultProcessLanguage: Language; defaultProcessLanguage: Language;
defaultTranslateTargetLanguage: Language; defaultTranslateTargetLanguage: Language;
IsHosted: boolean; isHosted: boolean;
static createFrom(source: any = {}) { static createFrom(source: any = {}) {
return new ProjectSettings(source); return new ProjectSettings(source);
@ -391,7 +393,7 @@ export namespace ipc {
if ('string' === typeof source) source = JSON.parse(source); if ('string' === typeof source) source = JSON.parse(source);
this.defaultProcessLanguage = this.convertValues(source["defaultProcessLanguage"], Language); this.defaultProcessLanguage = this.convertValues(source["defaultProcessLanguage"], Language);
this.defaultTranslateTargetLanguage = this.convertValues(source["defaultTranslateTargetLanguage"], Language); this.defaultTranslateTargetLanguage = this.convertValues(source["defaultTranslateTargetLanguage"], Language);
this.IsHosted = source["IsHosted"]; this.isHosted = source["isHosted"];
} }
convertValues(a: any, classs: any, asMap: boolean = false): any { convertValues(a: any, classs: any, asMap: boolean = false): any {

View File

@ -3,6 +3,7 @@ package ipc
import ( import (
"sort" "sort"
app "textualize/core/App" app "textualize/core/App"
consts "textualize/core/Consts"
document "textualize/core/Document" document "textualize/core/Document"
session "textualize/core/Session" session "textualize/core/Session"
@ -67,10 +68,6 @@ func (c *Channel) GetDocuments() GetDocumentsResponse {
}) })
} }
// sort.Slice(jsonAreas, func(i, j int) bool {
// return jsonAreas[i].Order < jsonAreas[j].Order
// })
sort.Slice(jsonAreas, func(i, j int) bool { sort.Slice(jsonAreas, func(i, j int) bool {
return jsonAreas[i].Order < jsonAreas[j].Order return jsonAreas[i].Order < jsonAreas[j].Order
}) })
@ -87,16 +84,24 @@ func (c *Channel) GetDocuments() GetDocumentsResponse {
response.Documents = append(response.Documents, jsonDocument) response.Documents = append(response.Documents, jsonDocument)
} }
jsonGroups := make([]Group, 0)
for _, g := range groups { for _, g := range groups {
jsonGroup := Group{ jsonGroup := Group{
Id: g.Id, Id: g.Id,
ParentId: g.ParentId, ParentId: g.ParentId,
ProjectId: g.ProjectId, ProjectId: g.ProjectId,
Name: g.Name, Name: g.Name,
Order: g.Order,
} }
response.Groups = append(response.Groups, jsonGroup) jsonGroups = append(jsonGroups, jsonGroup)
} }
sort.Slice(jsonGroups, func(i, j int) bool {
return jsonGroups[i].Order < jsonGroups[j].Order
})
response.Groups = jsonGroups
return response return response
} }
@ -176,24 +181,68 @@ func (c *Channel) GetUserMarkdownByDocumentId(documentId string) UserMarkdown {
} }
func (c *Channel) RequestAddDocumentGroup(name string) Group { func (c *Channel) RequestAddDocumentGroup(name string) Group {
groupCollection := document.GetGroupCollection()
newGroup := document.Group{ newGroup := document.Group{
Id: uuid.NewString(), Id: uuid.NewString(),
Name: name, Name: name,
ProjectId: session.GetInstance().Project.Id, ProjectId: session.GetInstance().Project.Id,
Order: len(groupCollection.Groups),
} }
document.GetGroupCollection().AddDocumentGroup(newGroup) groupCollection.AddDocumentGroup(newGroup)
response := Group{ response := Group{
Id: newGroup.Id, Id: newGroup.Id,
Name: newGroup.Name, Name: newGroup.Name,
ParentId: newGroup.ParentId, ParentId: newGroup.ParentId,
ProjectId: newGroup.ProjectId, ProjectId: newGroup.ProjectId,
Order: newGroup.Order,
} }
return response return response
} }
func (c *Channel) RequestChangeGroupOrder(groupId string, newOrder int) Group {
groupCollection := document.GetGroupCollection()
// var foundArea document.Area
// for _, a := range documentOfArea.Areas {
// if a.Id == areaId {
// foundArea = a
// break
// }
// }
// if foundArea.Id == "" {
// return Document{}
// }
// processedAreasCollection := document.GetProcessedAreaCollection()
// for index, a := range documentOfArea.Areas {
// if a.Id == areaId {
// documentOfArea.Areas[index].Order = newOrder
// processedAreasCollection.GetAreaById(a.Id).Order = newOrder
// } else if a.Order >= newOrder {
// documentOfArea.Areas[index].Order = a.Order + 1
// processedAreasCollection.GetAreaById(a.Id).Order = a.Order + 1
// }
// }
for _, g := range groupCollection.Groups {
if g.Id == groupId {
// document.GetGroupCollection().Groups[index].Order = newOrder
document.GetGroupCollection().GetGroupById(groupId).Order = newOrder
} else if g.Order >= newOrder {
// document.GetGroupCollection().Groups[index].Order = g.Order + 1
document.GetGroupCollection().GetGroupById(groupId).Order = g.Order + 1
}
}
return Group(*document.GetGroupCollection().GetGroupById(groupId))
}
func (c *Channel) GetAreaById(areaId string) Area { func (c *Channel) GetAreaById(areaId string) Area {
foundDocument := document.GetDocumentCollection().GetDocumentByAreaId(areaId) foundDocument := document.GetDocumentCollection().GetDocumentByAreaId(areaId)
@ -243,7 +292,7 @@ func (c *Channel) RequestAddArea(documentId string, area Area) Area {
StartY: area.StartY, StartY: area.StartY,
EndY: area.EndY, EndY: area.EndY,
Order: order, Order: order,
Language: app.Language(area.Language), Language: consts.Language(area.Language),
} }
foundDocument.AddArea(newArea) foundDocument.AddArea(newArea)
@ -337,7 +386,7 @@ func (c *Channel) RequestUpdateDocument(updatedDocument Document) Document {
documentToUpdate.Path = updatedDocument.Path documentToUpdate.Path = updatedDocument.Path
} }
if updatedDocument.DefaultLanguage.DisplayName != "" { if updatedDocument.DefaultLanguage.DisplayName != "" {
documentToUpdate.DefaultLanguage = app.Language(updatedDocument.DefaultLanguage) documentToUpdate.DefaultLanguage = consts.Language(updatedDocument.DefaultLanguage)
} }
return updatedDocument return updatedDocument

View File

@ -20,6 +20,7 @@ type Group struct {
ParentId string `json:"parentId"` ParentId string `json:"parentId"`
ProjectId string `json:"projectId"` ProjectId string `json:"projectId"`
Name string `json:"name"` Name string `json:"name"`
Order int `json:"order"`
} }
type GroupCollection struct { type GroupCollection struct {
@ -110,7 +111,7 @@ type Project struct {
type ProjectSettings struct { type ProjectSettings struct {
DefaultProcessLanguage Language `json:"defaultProcessLanguage"` DefaultProcessLanguage Language `json:"defaultProcessLanguage"`
DefaultTranslateTargetLanguage Language `json:"defaultTranslateTargetLanguage"` DefaultTranslateTargetLanguage Language `json:"defaultTranslateTargetLanguage"`
IsHosted bool `json:"IsHosted"` IsHosted bool `json:"isHosted"`
} }
type Session struct { type Session struct {

View File

@ -2,7 +2,9 @@ package ipc
import ( import (
app "textualize/core/App" app "textualize/core/App"
consts "textualize/core/Consts"
session "textualize/core/Session" session "textualize/core/Session"
storage "textualize/storage/Local"
"github.com/wailsapp/wails/v2/pkg/runtime" "github.com/wailsapp/wails/v2/pkg/runtime"
@ -46,12 +48,24 @@ func (c *Channel) GetCurrentSession() Session {
func (c *Channel) CreateNewProject(name string) Session { func (c *Channel) CreateNewProject(name string) Session {
currentSession := session.GetInstance() currentSession := session.GetInstance()
currentSession.Project = session.Project{ newProject := session.Project{
Id: uuid.NewString(), Id: uuid.NewString(),
OrganizationId: currentSession.Project.OrganizationId, OrganizationId: currentSession.Project.OrganizationId,
Name: name, Name: name,
} }
successfulProjectWrite := storage.WriteLocalProjectData(storage.LocalProject{
Id: uuid.NewString(),
OrganizationId: currentSession.Project.OrganizationId,
Name: name,
})
if !successfulProjectWrite {
return Session{}
}
currentSession.Project = newProject
return c.GetCurrentSession() return c.GetCurrentSession()
} }
@ -62,24 +76,30 @@ func (c *Channel) GetCurrentUser() User {
func (c *Channel) RequestUpdateCurrentUser(updatedUserRequest User) User { func (c *Channel) RequestUpdateCurrentUser(updatedUserRequest User) User {
sessionInstance := session.GetInstance() sessionInstance := session.GetInstance()
user := session.User(sessionInstance.User) sessionUser := session.User(sessionInstance.User)
if user.LocalId == "" { if sessionUser.LocalId == "" {
user.LocalId = uuid.NewString() sessionUser.LocalId = uuid.NewString()
} }
if updatedUserRequest.FirstName != "" { if updatedUserRequest.FirstName != "" {
user.FirstName = updatedUserRequest.FirstName sessionUser.FirstName = updatedUserRequest.FirstName
} }
if updatedUserRequest.LastName != "" { if updatedUserRequest.LastName != "" {
user.LastName = updatedUserRequest.LastName sessionUser.LastName = updatedUserRequest.LastName
} }
if updatedUserRequest.Email != "" { if updatedUserRequest.Email != "" {
user.Email = updatedUserRequest.Email sessionUser.Email = updatedUserRequest.Email
} }
user.AvatarPath = updatedUserRequest.AvatarPath sessionUser.AvatarPath = updatedUserRequest.AvatarPath
successfulUserWrite := storage.WriteLocalUserData(storage.LocalUser(sessionUser))
if !successfulUserWrite {
return User{}
}
sessionInstance.UpdateCurrentUser(sessionUser)
sessionInstance.UpdateCurrentUser(user)
return User(sessionInstance.User) return User(sessionInstance.User)
} }
@ -102,8 +122,68 @@ func (c *Channel) RequestChooseUserAvatar() string {
} }
} }
func (c *Channel) GetAllLocalProjects() []Project {
readLocalProjects := storage.ReadAllLocalProjects()
response := make([]Project, 0)
for _, p := range readLocalProjects {
response = append(response, Project{
Id: p.Id,
OrganizationId: p.OrganizationId,
Name: p.Name,
Settings: ProjectSettings{
DefaultProcessLanguage: Language(p.Settings.DefaultProcessLanguage),
DefaultTranslateTargetLanguage: Language(p.Settings.DefaultTranslateTargetLanguage),
IsHosted: p.Settings.IsHosted,
},
})
}
return response
}
func (c *Channel) GetProjectByName(projectName string) Project {
foundProject := storage.ReadLocalProjectByName(projectName)
if foundProject.Id == "" {
return Project{}
}
return Project{
Id: foundProject.Id,
Name: foundProject.Name,
OrganizationId: foundProject.OrganizationId,
Settings: ProjectSettings{
DefaultProcessLanguage: Language(foundProject.Settings.DefaultProcessLanguage),
DefaultTranslateTargetLanguage: Language(foundProject.Settings.DefaultTranslateTargetLanguage),
IsHosted: foundProject.Settings.IsHosted,
},
}
}
func (c *Channel) RequestChangeSessionProjectByName(projectName string) bool {
foundProject := c.GetProjectByName(projectName)
if foundProject.Id == "" {
return false
}
session.GetInstance().Project = session.Project{
Id: foundProject.Id,
Name: foundProject.Name,
OrganizationId: foundProject.OrganizationId,
Settings: session.ProjectSettings{
DefaultProcessLanguage: consts.Language(foundProject.Settings.DefaultProcessLanguage),
DefaultTranslateTargetLanguage: consts.Language(foundProject.Settings.DefaultTranslateTargetLanguage),
IsHosted: foundProject.Settings.IsHosted,
},
}
return session.GetInstance().Project.Id == foundProject.Id
}
func (c *Channel) GetSuppportedLanguages() []Language { func (c *Channel) GetSuppportedLanguages() []Language {
supportedLanguages := app.GetSuppportedLanguages() supportedLanguages := consts.GetSuppportedLanguages()
var response []Language var response []Language

View File

@ -7,9 +7,8 @@ import (
"net/http" "net/http"
"os" "os"
ipc "textualize/Ipc"
app "textualize/core/App" app "textualize/core/App"
document "textualize/core/Document"
ipc "textualize/ipc"
"github.com/wailsapp/wails/v2" "github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/logger" "github.com/wailsapp/wails/v2/pkg/logger"
@ -50,8 +49,6 @@ var icon []byte
func main() { func main() {
// Create an instance of the app structure // Create an instance of the app structure
app := app.GetInstance() app := app.GetInstance()
document.InitizeModule()
ipcChannel := ipc.GetInstance() ipcChannel := ipc.GetInstance()
// Create application with options // Create application with options

150
storage/Local/Interface.go Normal file
View File

@ -0,0 +1,150 @@
package storage
import (
"encoding/json"
"fmt"
"os"
"strings"
)
func GetLocalStoragePath() string {
homeDir, err := os.UserHomeDir()
applicationName := "/Textualize"
if err != nil {
return ""
}
return homeDir + applicationName
}
func createLocalStorageDirIfNeeded() bool {
localStoragePath := GetLocalStoragePath()
if localStoragePath == "" {
return false
}
_, directoryError := os.Stat(GetLocalStoragePath())
directoryDoesNotExist := os.IsNotExist(directoryError)
if !directoryDoesNotExist {
return true
}
errorCreatingDir := os.Mkdir(localStoragePath, os.ModePerm)
return errorCreatingDir != nil
}
func createLocalStorageSubDirIfNeeded(relativeSubdirectoryPath string) bool {
localStoragePath := GetLocalStoragePath()
if localStoragePath == "" {
return false
}
fullLocalStoragePath := GetLocalStoragePath() + relativeSubdirectoryPath
_, directoryError := os.Stat(fullLocalStoragePath)
directoryDoesNotExist := os.IsNotExist(directoryError)
if !directoryDoesNotExist {
return true
}
errorCreatingDir := os.MkdirAll(fullLocalStoragePath, os.ModePerm)
return errorCreatingDir != nil
}
func WriteLocalUserData(user LocalUser) bool {
file, _ := json.MarshalIndent(user, "", " ")
path := GetLocalStoragePath()
if path == "" {
return false
}
isLocalStorageDirectoryCreated := createLocalStorageDirIfNeeded()
if !isLocalStorageDirectoryCreated {
return false
}
err := os.WriteFile(GetLocalStoragePath()+"/User.json", file, 0644)
return err == nil
}
func ReadLocalUserData() LocalUser {
file, err := os.ReadFile(GetLocalStoragePath() + "/User.json")
if err != nil {
return LocalUser{}
}
response := LocalUser{}
errorUnmarshaling := json.Unmarshal([]byte(file), &response)
if errorUnmarshaling != nil {
return LocalUser{}
}
return response
}
func ReadLocalProjectByName(name string) LocalProject {
file, err := os.ReadFile(GetLocalStoragePath() + "/projects/" + name + ".json")
if err != nil {
return LocalProject{}
}
response := LocalProject{}
errorUnmarshaling := json.Unmarshal([]byte(file), &response)
if errorUnmarshaling != nil {
return LocalProject{}
}
return response
}
func WriteLocalProjectData(project LocalProject) bool {
file, _ := json.MarshalIndent(project, "", " ")
path := GetLocalStoragePath()
if path == "" {
return false
}
subdirectory := "/projects/"
isLocalStorageDirectoryCreated := createLocalStorageSubDirIfNeeded(subdirectory)
if !isLocalStorageDirectoryCreated {
return false
}
err := os.WriteFile(GetLocalStoragePath()+subdirectory+project.Name+".json", file, 0644)
return err == nil
}
func ReadAllLocalProjects() []LocalProject {
localProjects := make([]LocalProject, 0)
subdirectory := "/projects/"
isLocalStorageDirectoryCreated := createLocalStorageSubDirIfNeeded(subdirectory)
if !isLocalStorageDirectoryCreated {
return localProjects
}
localProjectFileEntries, readDirError := os.ReadDir(GetLocalStoragePath() + subdirectory)
if readDirError != nil {
fmt.Println(localProjectFileEntries)
return localProjects
}
localProjectNames := make([]string, 0)
for _, fileName := range localProjectFileEntries {
localProjectNames = append(localProjectNames, strings.ReplaceAll(fileName.Name(), ".json", ""))
}
for _, projectName := range localProjectNames {
localProjects = append(localProjects, ReadLocalProjectByName(projectName))
}
return localProjects
}

View File

@ -0,0 +1,30 @@
package storage
type LocalProject struct {
Id string `json:"id"`
OrganizationId string `json:"organizationId"`
Name string `json:"name"`
Settings LocalProjectSettings `json:"settings"`
}
type LocalProjectSettings struct {
DefaultProcessLanguage Language `json:"defaultProcessLanguage"`
DefaultTranslateTargetLanguage Language `json:"defaultTranslateTargetLanguage"`
IsHosted bool `json:"isHosted"`
}
type Language struct {
DisplayName string `json:"displayName"`
ProcessCode string `json:"processCode"`
TranslateCode string `json:"translateCode"`
}
type LocalUser struct {
Id string `json:"id"`
LocalId string `json:"localId"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
AvatarPath string `json:"avatarPath"`
AuthToken string `json:"authToken"`
Email string `json:"email"`
}