feat: render selected document
This commit is contained in:
parent
9ab224f70c
commit
acf93695d3
@ -18,3 +18,16 @@ func GetDocumentCollection() *DocumentCollection {
|
||||
func (collection *DocumentCollection) AddDocument(document Entity) {
|
||||
collection.Documents = append(collection.Documents, document)
|
||||
}
|
||||
|
||||
func (collection *DocumentCollection) GetDocumentById(id string) Entity {
|
||||
var foundDocument Entity
|
||||
|
||||
for _, d := range collection.Documents {
|
||||
if d.Id == id {
|
||||
foundDocument = d
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return foundDocument
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'server-only'
|
||||
import MainHead from '../components/MainHead'
|
||||
import DocumentRenderer from '../components/workspace/DocumentRenderer'
|
||||
import Navigation from '../components/workspace/Navigation'
|
||||
|
||||
export default function Home() {
|
||||
@ -16,8 +17,8 @@ export default function Home() {
|
||||
</div>
|
||||
<div className="mx-auto px-4 sm:px-6 md:px-8">
|
||||
<div className="py-4">
|
||||
<div className="h-96 rounded-lg border-4 border-dashed border-gray-200">
|
||||
{/* Add canvas */}
|
||||
<div className=" min-h-96 rounded-lg border-4 border-dashed border-gray-200">
|
||||
<DocumentRenderer />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
44
frontend/components/workspace/DocumentRenderer.tsx
Normal file
44
frontend/components/workspace/DocumentRenderer.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useRef } from "react"
|
||||
import { useProject } from "../../context/Project/provider"
|
||||
|
||||
|
||||
const loadImage = (path: string): Promise<HTMLImageElement> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const image = new Image()
|
||||
image.src = path
|
||||
image.onload = () => resolve(image)
|
||||
image.onerror = (error) => reject(error)
|
||||
})
|
||||
}
|
||||
|
||||
const DocumentRenderer = () => {
|
||||
const { getSelectedDocument } = useProject()
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null)
|
||||
|
||||
const applyDocumentToCanvas = async (path: string) => {
|
||||
const image = await loadImage(path)
|
||||
|
||||
const canvas = canvasRef.current
|
||||
if (!canvas) return
|
||||
canvas.width = image.naturalWidth
|
||||
canvas.height = image.naturalHeight
|
||||
|
||||
const context = canvas.getContext('2d')
|
||||
if (!context) return
|
||||
context.drawImage(image, 10, 10, image.width, image.height)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const selectedDocument = getSelectedDocument()
|
||||
const documentPath = selectedDocument?.path
|
||||
if (documentPath) applyDocumentToCanvas(selectedDocument.path)
|
||||
}, [getSelectedDocument])
|
||||
|
||||
return (
|
||||
<canvas ref={canvasRef}></canvas>
|
||||
)
|
||||
}
|
||||
|
||||
export default DocumentRenderer
|
@ -43,14 +43,20 @@ function classNames(...classes: any[]) {
|
||||
}
|
||||
|
||||
function Sidebar() {
|
||||
const [selectedItemId, setSelectedItemId] = useState('')
|
||||
const [selectedGroupId, setSelectedGroupId] = useState('')
|
||||
const [isAddNewDocumentInputShowing, setIsAddNewDocumentInputShowing] = useState(false)
|
||||
const [isAddNewGroupInputShowing, setIsAddNewGroupInputShowing] = useState(false)
|
||||
const addDocumentTextInput = useRef<HTMLInputElement>(null)
|
||||
const addGroupTextInput = useRef<HTMLInputElement>(null)
|
||||
|
||||
const { documents, groups, requestAddDocument, requestAddDocumentGroup } = useProject()
|
||||
const {
|
||||
documents,
|
||||
groups,
|
||||
requestAddDocument,
|
||||
requestAddDocumentGroup,
|
||||
selectedDocumentId,
|
||||
setSelectedDocumentId
|
||||
} = useProject()
|
||||
|
||||
const navigation = getNavigationProps(documents, groups)
|
||||
|
||||
@ -75,7 +81,7 @@ function Sidebar() {
|
||||
}
|
||||
|
||||
const onItemClickHandler = (itemId: string) => {
|
||||
setSelectedItemId(itemId)
|
||||
setSelectedDocumentId(itemId)
|
||||
setSelectedGroupId(getParentGroupIdFromItemId(itemId))
|
||||
setIsAddNewDocumentInputShowing(false)
|
||||
setIsAddNewGroupInputShowing(false)
|
||||
@ -96,12 +102,15 @@ function Sidebar() {
|
||||
const response = await requestAddDocument(groupId, documentName)
|
||||
if (!response.id) return
|
||||
|
||||
setSelectedItemId(response.id)
|
||||
|
||||
setSelectedDocumentId(response.id)
|
||||
|
||||
|
||||
setSelectedGroupId(groupId)
|
||||
setIsAddNewDocumentInputShowing(false)
|
||||
}
|
||||
|
||||
const onConfirmAddGroupClickHandler = async(e: React.MouseEvent) => {
|
||||
const onConfirmAddGroupClickHandler = async (e: React.MouseEvent) => {
|
||||
const groupName = addGroupTextInput.current?.value
|
||||
if (!groupName) return
|
||||
|
||||
@ -219,7 +228,7 @@ function Sidebar() {
|
||||
role='button'
|
||||
onClick={() => onItemClickHandler(child.id)}
|
||||
className={classNames(
|
||||
child.id === selectedItemId
|
||||
child.id === selectedDocumentId
|
||||
? 'bg-gray-900 text-white'
|
||||
: 'text-gray-300 hover:bg-gray-700 hover:text-white',
|
||||
'group w-full flex items-center pr-2 py-2 text-left font-medium text-sm rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 p-2'
|
||||
|
@ -14,6 +14,7 @@ type Props = { children: ReactNode, projectProps: ProjectProps }
|
||||
export function ProjectProvider({ children, projectProps }: Props) {
|
||||
const [ documents, setDocuments ] = useState<ipc.Document[]>(projectProps.documents)
|
||||
const [ groups, setGroups ] = useState<ipc.Group[]>(projectProps.groups)
|
||||
const [selectedDocumentId, setSelectedDocumentId] = useState<string>('')
|
||||
|
||||
const updateDocuments = async () => {
|
||||
GetDocuments().then(response => {
|
||||
@ -35,14 +36,19 @@ export function ProjectProvider({ children, projectProps }: Props) {
|
||||
return response
|
||||
}
|
||||
|
||||
const getSelectedDocument = () => documents.find(d => d.id === selectedDocumentId)
|
||||
|
||||
if (!documents.length || !groups.length) updateDocuments()
|
||||
|
||||
const value = {
|
||||
id: '',
|
||||
documents,
|
||||
groups,
|
||||
getSelectedDocument,
|
||||
requestAddDocument,
|
||||
requestAddDocumentGroup,
|
||||
selectedDocumentId,
|
||||
setSelectedDocumentId,
|
||||
}
|
||||
|
||||
return <ProjectContext.Provider value={value}>
|
||||
|
@ -7,6 +7,9 @@ export type ProjectProps = {
|
||||
}
|
||||
|
||||
export type ProjectContextType = {
|
||||
getSelectedDocument: () => ipc.Document | undefined
|
||||
requestAddDocument: (groupId: string, documentName: string) => Promise<ipc.Document>,
|
||||
requestAddDocumentGroup: (groupName: string) => Promise<ipc.Group>,
|
||||
selectedDocumentId: string,
|
||||
setSelectedDocumentId: (id: string) => void,
|
||||
} & ProjectProps
|
27
main.go
27
main.go
@ -2,7 +2,10 @@ package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
app "textualize/core/App"
|
||||
document "textualize/core/Document"
|
||||
@ -11,6 +14,7 @@ import (
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/assetserver"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/mac"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/windows"
|
||||
)
|
||||
@ -18,6 +22,26 @@ import (
|
||||
//go:embed frontend/out frontend/out/_next/static
|
||||
var assets embed.FS
|
||||
|
||||
type FileLoader struct {
|
||||
http.Handler
|
||||
}
|
||||
|
||||
func ClientFileLoader() *FileLoader {
|
||||
return &FileLoader{}
|
||||
}
|
||||
|
||||
func (h *FileLoader) ServeHTTP(res http.ResponseWriter, req *http.Request) {
|
||||
var err error
|
||||
requestedFilename := req.URL.Path
|
||||
fileData, err := os.ReadFile(requestedFilename)
|
||||
if err != nil {
|
||||
res.WriteHeader(http.StatusBadRequest)
|
||||
res.Write([]byte(fmt.Sprintf("Could not load file %s", requestedFilename)))
|
||||
}
|
||||
|
||||
res.Write(fileData)
|
||||
}
|
||||
|
||||
//go:embed build/appicondark.png
|
||||
var icon []byte
|
||||
|
||||
@ -43,7 +67,10 @@ func main() {
|
||||
StartHidden: false,
|
||||
HideWindowOnClose: false,
|
||||
BackgroundColour: &options.RGBA{R: 255, G: 255, B: 255, A: 255},
|
||||
AssetServer: &assetserver.Options{
|
||||
Assets: assets,
|
||||
Handler: ClientFileLoader(),
|
||||
},
|
||||
Menu: nil,
|
||||
Logger: nil,
|
||||
LogLevel: logger.DEBUG,
|
||||
|
Loading…
x
Reference in New Issue
Block a user