feat: render selected document

This commit is contained in:
Joshua Shoemaker 2022-12-13 16:51:56 -06:00
parent 9ab224f70c
commit acf93695d3
7 changed files with 117 additions and 14 deletions

View File

@ -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
}

View File

@ -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>

View 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

View File

@ -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'

View File

@ -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}>

View File

@ -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
View File

@ -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,