feat: zoom doc and delete area

This commit is contained in:
Joshua Shoemaker 2023-03-22 00:53:21 -05:00
parent f0d0c609b3
commit 49db0aff66
9 changed files with 200 additions and 79 deletions

View File

@ -1,19 +1,26 @@
'use client' 'use client'
import React, { useEffect, useRef } from 'react' import { MagnifyingGlassMinusIcon, MagnifyingGlassPlusIcon } from '@heroicons/react/24/outline'
import React, { useEffect, useRef, useState, WheelEvent } from 'react'
import { useProject } from '../../context/Project/provider' import { useProject } from '../../context/Project/provider'
import loadImage from '../../useCases/loadImage' import loadImage from '../../useCases/loadImage'
import processImageArea from '../../useCases/processImageArea' import processImageArea from '../../useCases/processImageArea'
import classNames from '../../utils/classNames'
import LanguageSelect from './LanguageSelect' import LanguageSelect from './LanguageSelect'
const zoomStep = 0.05
const maxZoomLevel = 4
const DocumentRenderer = () => { const DocumentRenderer = () => {
const { getSelectedDocument, requestAddArea } = useProject() const { getSelectedDocument, requestAddArea, selectedAreaId, setSelectedAreaId } = useProject()
const selectedDocument = getSelectedDocument() const selectedDocument = getSelectedDocument()
const areas = selectedDocument?.areas const areas = selectedDocument?.areas
const documentCanvas = useRef<HTMLCanvasElement>(null) const documentCanvas = useRef<HTMLCanvasElement>(null)
const areaCanvas = useRef<HTMLCanvasElement>(null) const areaCanvas = useRef<HTMLCanvasElement>(null)
const drawingCanvas = useRef<HTMLCanvasElement>(null) const drawingCanvas = useRef<HTMLCanvasElement>(null)
const [zoomLevel, setZoomLevel] = useState(1)
let downClickX = 0 let downClickX = 0
let downClickY = 0 let downClickY = 0
let isMouseDown = false let isMouseDown = false
@ -43,14 +50,17 @@ const DocumentRenderer = () => {
return return
} }
applyCanvasSizes({ width: image.naturalWidth, height: image.naturalHeight }) const width = image.naturalWidth * zoomLevel
const height = image.naturalHeight * zoomLevel
applyCanvasSizes({ width, height })
const documentCanvasInstance = documentCanvas.current const documentCanvasInstance = documentCanvas.current
if (!documentCanvasInstance) return if (!documentCanvasInstance) return
const context = documentCanvasInstance.getContext('2d') const context = documentCanvasInstance.getContext('2d')
if (!context) return if (!context) return
context.drawImage(image, 0, 0, image.width, image.height) context.drawImage(image, 0, 0, width, height)
if (areas) applyAreasToCanvas() if (areas) applyAreasToCanvas()
} }
@ -58,7 +68,7 @@ const DocumentRenderer = () => {
const applyAreasToCanvas = () => { const applyAreasToCanvas = () => {
const areaCanvasInstance = areaCanvas.current const areaCanvasInstance = areaCanvas.current
if (!areaCanvasInstance) return if (!areaCanvasInstance) return
const context = areaCanvasInstance.getContext('2d') const context = areaCanvasInstance.getContext('2d')!
if (!context) return if (!context) return
context.clearRect(0, 0, areaCanvasInstance.width, areaCanvasInstance.height) context.clearRect(0, 0, areaCanvasInstance.width, areaCanvasInstance.height)
@ -66,14 +76,23 @@ const DocumentRenderer = () => {
if (!areas || !areas.length) return if (!areas || !areas.length) return
areas.forEach(a => { areas.forEach(a => {
const width = a.endX - a.startX context.beginPath()
const height = a.endY - a.startY if (a.id !== selectedAreaId) {
const x = a.startX context.setLineDash([4])
const y = a.startY context.lineWidth = 2
context.rect(x, y, width, height) context.strokeStyle = '#010101'
context.lineWidth = 2 } else {
context.strokeStyle = '#dc8dec' context.setLineDash([])
context.lineWidth = 3
context.strokeStyle = '#dc8dec'
}
const width = (a.endX - a.startX) * zoomLevel
const height = (a.endY - a.startY) * zoomLevel
const x = a.startX * zoomLevel
const y = a.startY * zoomLevel
context.roundRect(x, y, width, height, 4)
context.stroke() context.stroke()
context.closePath()
}) })
} }
@ -95,25 +114,26 @@ const DocumentRenderer = () => {
let startX: number, endX: number let startX: number, endX: number
if (downClickX < mouseX) { if (downClickX < mouseX) {
startX = downClickX startX = Math.floor(downClickX / zoomLevel)
endX = mouseX endX = Math.floor(mouseX / zoomLevel)
} else { } else {
startX = mouseX startX = Math.floor(mouseX / zoomLevel)
endX = downClickX endX = Math.floor(downClickX / zoomLevel)
} }
let startY: number, endY: number let startY: number, endY: number
if (downClickY < mouseY) { if (downClickY < mouseY) {
startY = downClickY startY = Math.floor(downClickY / zoomLevel)
endY = mouseY endY = Math.floor(mouseY / zoomLevel)
} else { } else {
startY = mouseY startY = Math.floor(mouseY / zoomLevel)
endY = downClickY endY = Math.floor(downClickY / zoomLevel)
} }
if (selectedDocument?.id) { if (selectedDocument?.id) {
const addedArea = await requestAddArea(selectedDocument.id, { startX, startY, endX, endY }) const addedArea = await requestAddArea(selectedDocument.id, { startX, startY, endX, endY })
processImageArea(selectedDocument.id, addedArea) setSelectedAreaId(addedArea.id)
processImageArea(selectedDocument.id, addedArea.id)
} }
const context = drawingCanvasInstance.getContext('2d') const context = drawingCanvasInstance.getContext('2d')
@ -145,9 +165,16 @@ const DocumentRenderer = () => {
} }
} }
const handleWheelEvent = (e: WheelEvent<HTMLDivElement>) => {
if (!e.ctrlKey) return
const shouldAttemptToZoomIn = (e.deltaY < 0) && zoomLevel < maxZoomLevel
if (shouldAttemptToZoomIn) setZoomLevel(zoomLevel + zoomStep)
else if (zoomLevel > (zoomStep * 2)) setZoomLevel(zoomLevel - zoomStep)
}
useEffect(() => { useEffect(() => {
if (selectedDocument?.path) applyDocumentToCanvas(selectedDocument.path) if (selectedDocument?.path) applyDocumentToCanvas(selectedDocument.path)
applyAreasToCanvas()
}) })
return <div className='relative'> return <div className='relative'>
@ -155,26 +182,42 @@ const DocumentRenderer = () => {
<h1 className="text-2xl font-semibold text-gray-900"> <h1 className="text-2xl font-semibold text-gray-900">
{getSelectedDocument()?.name} {getSelectedDocument()?.name}
</h1> </h1>
<LanguageSelect shouldUpdateDocument defaultLanguage={selectedDocument?.defaultLanguage} /> <div>
<LanguageSelect shouldUpdateDocument defaultLanguage={selectedDocument?.defaultLanguage} />
<div className='flex justify-evenly items-center mt-2 mb-0'>
<MagnifyingGlassMinusIcon className='w-4 h-4' />
<input
id="zoomRange" type="range" min={zoomStep} max={maxZoomLevel} step={zoomStep}
value={zoomLevel} className="w-[calc(100%-50px)] h-2 bg-indigo-200 rounded-lg appearance-none cursor-pointer p-0"
onChange={(e) => { setZoomLevel(e.currentTarget.valueAsNumber) }}
/>
<MagnifyingGlassPlusIcon className='w-4 h-4' />
</div>
</div>
</div> </div>
<div className="relative mt-2"> <div
onWheelCapture={handleWheelEvent}
className={classNames('relative mt-2 overflow-scroll',
'w-[calc(100vw-320px)] h-[calc(100vh-240px)] border-4',
'border-dashed border-gray-200')}>
<canvas <canvas
className="absolute border-4 border-dashed border-gray-200" className="absolute"
ref={documentCanvas} ref={documentCanvas}
/> />
<canvas <canvas
className="absolute border-4 border-transparent" className="absolute "
ref={areaCanvas} ref={areaCanvas}
/> />
<canvas <canvas
className="absolute border-4 border-transparent" className="absolute"
ref={drawingCanvas} ref={drawingCanvas}
onMouseDown={handleMouseDown} onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp} onMouseUp={handleMouseUp}
onMouseMove={handleMouseMove} onMouseMove={handleMouseMove}
/> />
</div> </div>
</div> </div >
} }
export default DocumentRenderer export default DocumentRenderer

View File

@ -70,6 +70,7 @@ function Sidebar() {
getSelectedDocument, getSelectedDocument,
getAreaById, getAreaById,
requestUpdateArea, requestUpdateArea,
requestDeleteAreaById,
requestAddDocument, requestAddDocument,
requestAddDocumentGroup, requestAddDocumentGroup,
selectedAreaId, selectedAreaId,
@ -128,34 +129,24 @@ function Sidebar() {
setIsEditAreaNameInputShowing(false) setIsEditAreaNameInputShowing(false)
} }
// ________________
const onAreaDragOver = (areaId: string) => { const onAreaDragOver = (areaId: string) => {
setDragOverAreaId(areaId) setDragOverAreaId(areaId)
} }
const onAreaDragStart = (areaId: string) => { const onAreaDragStart = (areaId: string) => {
// setDragStartAreaId(areaId) setSelectedAreaId(areaId)
} }
const onAreaDropEnd = (areaId: string) => { const onAreaDropEnd = (areaId: string) => {
const areaDroppedOn = navigation.map(n => n.documents).flat().map(d => d.areas).flat().find(a => a.id === dragOverAreaId) const areaDroppedOn = navigation.map(n => n.documents).flat().map(d => d.areas).flat().find(a => a.id === dragOverAreaId)
if (!areaDroppedOn) return if (!areaDroppedOn) return
requestChangeAreaOrder(areaId, areaDroppedOn.order) requestChangeAreaOrder(areaId, areaDroppedOn.order)
setDragOverAreaId('') setDragOverAreaId('')
} }
// ________________
const handleAreaDeleteButtonClick = (areaId: string) => {
requestDeleteAreaById(areaId)
}
const onDocumentClickHandler = (itemId: string) => { const onDocumentClickHandler = (itemId: string) => {
setSelectedDocumentId(itemId) setSelectedDocumentId(itemId)
@ -362,7 +353,7 @@ function Sidebar() {
name="documentName" name="documentName"
id="documentName" id="documentName"
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 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) => {
@ -397,12 +388,12 @@ function Sidebar() {
)}> )}>
{selectedDocumentId === d.id && isEditDocumentNameInputShowing {selectedDocumentId === d.id && isEditDocumentNameInputShowing
? <input // TODO: this ? <input
type="text" type="text"
name="documentName" name="documentName"
id="documentName" id="documentName"
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 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) => {
@ -434,7 +425,7 @@ function Sidebar() {
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 + 1}`} placeholder={a.name || `Area ${index}`}
onBlur={onAreaInputBlur} onBlur={onAreaInputBlur}
onKeyDown={(event) => { onKeyDown={(event) => {
onEnterHandler(event, onEnterHandler(event,
@ -442,23 +433,29 @@ function Sidebar() {
}} }}
ref={editAreaNameTextInput} ref={editAreaNameTextInput}
/> />
: <a : <div
role='button'
onClick={() => onAreaClick(a.id)}
onDoubleClick={() => onAreaDoubleClick(a.id)}
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('text-gray-300 hover:bg-gray-700 hover:text-white', className={classNames('flex justify-between items-center cursor-pointer',
'group w-full flex items-center pr-2 py-2 text-left font-medium pl-8 text-xs', selectedAreaId === a.id ? 'bg-indigo-500 text-gray-200' : 'text-gray-300 hover:bg-gray-700 hover:text-white',
'rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 py-2 select-none', dragOverAreaId === a.id ? 'bg-gray-300 text-gray-700' : '',
selectedAreaId === a.id ? 'underline' : '', selectedAreaId === a.id && dragOverAreaId === a.id ? 'bg-indigo-300' : '',
dragOverAreaId === a.id ? 'bg-gray-300 text-gray-700' : '' )}>
)} <a
> role='button'
{a.name || `Area ${a.order}`} onClick={() => onAreaClick(a.id)}
</a> onDoubleClick={() => onAreaDoubleClick(a.id)}
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',
)}>
{a.name || `Area ${a.order}`}
</a>
<XMarkIcon
className='w-5 h-5 mr-2 text-white hover:bg-white hover:text-gray-700 rounded-full p-0.5'
onClick={() => handleAreaDeleteButtonClick(a.id)} />
</div>
} }
</li> </li>
))} ))}

View File

@ -13,6 +13,7 @@ const makeDefaultProject = (): ProjectContextType => ({
requestAddProcessedArea: (processesArea) => Promise.resolve(new ipc.ProcessedArea()), requestAddProcessedArea: (processesArea) => Promise.resolve(new ipc.ProcessedArea()),
requestAddArea: (documentId, area) => Promise.resolve(new ipc.Area()), requestAddArea: (documentId, area) => Promise.resolve(new ipc.Area()),
requestUpdateArea: (updatedArea) => Promise.resolve(new ipc.Area()), requestUpdateArea: (updatedArea) => Promise.resolve(new ipc.Area()),
requestDeleteAreaById: (areaId) => Promise.resolve(false),
requestAddDocument: (groupId, documentName) => Promise.resolve(new ipc.Document()), requestAddDocument: (groupId, documentName) => Promise.resolve(new ipc.Document()),
requestAddDocumentGroup: (groupName: string) => Promise.resolve(new ipc.Group()), requestAddDocumentGroup: (groupName: string) => Promise.resolve(new ipc.Group()),
requestUpdateDocumentUserMarkdown: (documentId: string, markdown: string) => Promise.resolve(new ipc.UserMarkdown()), requestUpdateDocumentUserMarkdown: (documentId: string, markdown: string) => Promise.resolve(new ipc.UserMarkdown()),

View File

@ -9,6 +9,7 @@ import {
RequestChooseUserAvatar, RequestChooseUserAvatar,
RequestUpdateDocument, RequestUpdateDocument,
RequestChangeAreaOrder, RequestChangeAreaOrder,
RequestDeleteAreaById,
} 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'
@ -30,7 +31,6 @@ export function ProjectProvider({ children, projectProps }: Props) {
const updateDocuments = async () => { const updateDocuments = async () => {
GetDocuments().then(response => { GetDocuments().then(response => {
console.log(response)
if (response.documents.length) setDocuments(response.documents) if (response.documents.length) setDocuments(response.documents)
if (response.groups.length) setGroups(response.groups) if (response.groups.length) setGroups(response.groups)
Promise.resolve(response) Promise.resolve(response)
@ -66,6 +66,12 @@ export function ProjectProvider({ children, projectProps }: Props) {
documents.map(d => d.areas).flat().find(a => a.id === areaId) documents.map(d => d.areas).flat().find(a => a.id === areaId)
) )
const requestDeleteAreaById = async (areaId: string): Promise<boolean> => {
const wasSuccessfulDeletion = await RequestDeleteAreaById(areaId)
if (wasSuccessfulDeletion) updateDocuments()
return wasSuccessfulDeletion
}
const getSelectedDocument = () => documents.find(d => d.id === selectedDocumentId) const getSelectedDocument = () => documents.find(d => d.id === selectedDocumentId)
const getProcessedAreasByDocumentId = async (documentId: string) => { const getProcessedAreasByDocumentId = async (documentId: string) => {
@ -132,7 +138,6 @@ export function ProjectProvider({ children, projectProps }: Props) {
} }
const requestChangeAreaOrder = async (areaId: string, newOrder: number) => { const requestChangeAreaOrder = async (areaId: string, newOrder: number) => {
console.log('requestChangeAreaOrder')
const response = await RequestChangeAreaOrder(areaId, newOrder) const response = await RequestChangeAreaOrder(areaId, newOrder)
await updateDocuments() await updateDocuments()
return response return response
@ -152,6 +157,7 @@ export function ProjectProvider({ children, projectProps }: Props) {
requestAddDocument, requestAddDocument,
requestAddDocumentGroup, requestAddDocumentGroup,
requestUpdateArea, requestUpdateArea,
requestDeleteAreaById,
selectedAreaId, selectedAreaId,
setSelectedAreaId, setSelectedAreaId,
selectedDocumentId, selectedDocumentId,

View File

@ -43,6 +43,7 @@ export type ProjectContextType = {
requestAddProcessedArea: (processedArea: ipc.ProcessedArea) => Promise<ipc.ProcessedArea> requestAddProcessedArea: (processedArea: ipc.ProcessedArea) => Promise<ipc.ProcessedArea>
requestAddArea: (documentId: string, area: AddAreaProps) => Promise<ipc.Area> requestAddArea: (documentId: string, area: AddAreaProps) => Promise<ipc.Area>
requestUpdateArea: (area: AreaProps) => Promise<ipc.Area> requestUpdateArea: (area: AreaProps) => Promise<ipc.Area>
requestDeleteAreaById: (areaId: string) => Promise<boolean>
requestAddDocument: (groupId: string, documentName: string) => Promise<ipc.Document> requestAddDocument: (groupId: string, documentName: string) => Promise<ipc.Document>
requestAddDocumentGroup: (groupName: string) => Promise<ipc.Group> requestAddDocumentGroup: (groupName: string) => Promise<ipc.Group>
requestUpdateDocumentUserMarkdown: (documentId: string, markdown: string) => Promise<ipc.UserMarkdown> requestUpdateDocumentUserMarkdown: (documentId: string, markdown: string) => Promise<ipc.UserMarkdown>

View File

@ -1,32 +1,35 @@
import { createScheduler, createWorker } from 'tesseract.js' import { createScheduler, createWorker } from 'tesseract.js'
import { GetDocumentById, RequestAddProcessedArea } from '../wailsjs/wailsjs/go/ipc/Channel' import { GetAreaById, GetDocumentById, RequestAddProcessedArea } from '../wailsjs/wailsjs/go/ipc/Channel'
import { ipc } from '../wailsjs/wailsjs/go/models' import { ipc } from '../wailsjs/wailsjs/go/models'
import loadImage from './loadImage' import loadImage from './loadImage'
const processImageArea = async (documentId: string, area: ipc.Area) => { const processImageArea = async (documentId: string, areaId: string) => {
const foundDocument = await GetDocumentById(documentId) const foundDocument = await GetDocumentById(documentId)
if (!foundDocument.path || !foundDocument.areas?.length) return const foundArea = await GetAreaById(areaId)
if (!foundDocument.path || !foundDocument.areas?.length || !foundArea.id) return
const processLanguage = foundDocument.defaultLanguage.processCode
const { path } = foundDocument const { path } = foundDocument
const imageData = await loadImage(path) const imageData = await loadImage(path)
const scheduler = createScheduler() const scheduler = createScheduler()
const worker = await createWorker() const worker = await createWorker()
await worker.loadLanguage('eng') // TODO: change this when multilangiage system is implementd await worker.loadLanguage(processLanguage)
await worker.initialize('eng') // TODO: same here await worker.initialize(processLanguage)
scheduler.addWorker(worker) scheduler.addWorker(worker)
const result = await scheduler.addJob('recognize', imageData, { const result = await scheduler.addJob('recognize', imageData, {
rectangle: { rectangle: {
left: area.startX, left: foundArea.startX,
top: area.startY, top: foundArea.startY,
width: area.endX - area.startX, width: foundArea.endX - foundArea.startX,
height: area.endY - area.startY, height: foundArea.endY - foundArea.startY,
} }
}) })
const addProcessesAreaRequest = await RequestAddProcessedArea(new ipc.ProcessedArea({ const addProcessesAreaRequest = await RequestAddProcessedArea(new ipc.ProcessedArea({
id: area.id, id: foundArea.id,
documentId, documentId,
fullText: result.data.text, fullText: result.data.text,
lines: result.data.lines.map((l: any) => new ipc.ProcessedLine({ lines: result.data.lines.map((l: any) => new ipc.ProcessedLine({

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 GetAreaById(arg1:string):Promise<ipc.Area>;
export function GetCurrentSession():Promise<ipc.Session>; export function GetCurrentSession():Promise<ipc.Session>;
export function GetCurrentUser():Promise<ipc.User>; export function GetCurrentUser():Promise<ipc.User>;
@ -30,6 +32,8 @@ export function RequestChangeAreaOrder(arg1:string,arg2:number):Promise<ipc.Docu
export function RequestChooseUserAvatar():Promise<string>; export function RequestChooseUserAvatar():Promise<string>;
export function RequestDeleteAreaById(arg1:string):Promise<boolean>;
export function RequestUpdateArea(arg1:ipc.Area):Promise<ipc.Area>; export function RequestUpdateArea(arg1:ipc.Area):Promise<ipc.Area>;
export function RequestUpdateCurrentUser(arg1:ipc.User):Promise<ipc.User>; export function RequestUpdateCurrentUser(arg1:ipc.User):Promise<ipc.User>;

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 GetAreaById(arg1) {
return window['go']['ipc']['Channel']['GetAreaById'](arg1);
}
export function GetCurrentSession() { export function GetCurrentSession() {
return window['go']['ipc']['Channel']['GetCurrentSession'](); return window['go']['ipc']['Channel']['GetCurrentSession']();
} }
@ -58,6 +62,10 @@ export function RequestChooseUserAvatar() {
return window['go']['ipc']['Channel']['RequestChooseUserAvatar'](); return window['go']['ipc']['Channel']['RequestChooseUserAvatar']();
} }
export function RequestDeleteAreaById(arg1) {
return window['go']['ipc']['Channel']['RequestDeleteAreaById'](arg1);
}
export function RequestUpdateArea(arg1) { export function RequestUpdateArea(arg1) {
return window['go']['ipc']['Channel']['RequestUpdateArea'](arg1); return window['go']['ipc']['Channel']['RequestUpdateArea'](arg1);
} }

View File

@ -32,12 +32,13 @@ func (c *Channel) GetDocumentById(id string) Document {
}) })
} }
response := Document{ response := Document{
Id: foundDocument.Id, Id: foundDocument.Id,
Name: foundDocument.Name, Name: foundDocument.Name,
GroupId: foundDocument.GroupId, GroupId: foundDocument.GroupId,
Path: foundDocument.Path, Path: foundDocument.Path,
ProjectId: foundDocument.ProjectId, ProjectId: foundDocument.ProjectId,
Areas: jsonAreas, Areas: jsonAreas,
DefaultLanguage: Language(foundDocument.DefaultLanguage),
} }
return response return response
} }
@ -193,6 +194,32 @@ func (c *Channel) RequestAddDocumentGroup(name string) Group {
return response return response
} }
func (c *Channel) GetAreaById(areaId string) Area {
foundDocument := document.GetDocumentCollection().GetDocumentByAreaId(areaId)
if len(foundDocument.Areas) == 0 {
return Area{}
}
var foundArea document.Area
for i, a := range foundDocument.Areas {
if a.Id == areaId {
foundArea = foundDocument.Areas[i]
}
}
return Area{
Id: foundArea.Id,
Name: foundArea.Name,
StartX: foundArea.StartX,
EndX: foundArea.EndX,
StartY: foundArea.StartY,
EndY: foundArea.EndY,
Order: foundArea.Order,
Language: Language(foundArea.Language),
}
}
func (c *Channel) RequestAddArea(documentId string, area Area) Area { func (c *Channel) RequestAddArea(documentId string, area Area) Area {
foundDocument := document.GetDocumentCollection().GetDocumentById(documentId) foundDocument := document.GetDocumentCollection().GetDocumentById(documentId)
@ -233,7 +260,7 @@ func (c *Channel) RequestUpdateArea(updatedArea Area) Area {
return Area{} return Area{}
} }
areaToUpdate := documentOfArea.GetAreaById((updatedArea.Id)) areaToUpdate := documentOfArea.GetAreaById(updatedArea.Id)
if areaToUpdate.Id == "" { if areaToUpdate.Id == "" {
return Area{} return Area{}
@ -259,6 +286,37 @@ func (c *Channel) RequestUpdateArea(updatedArea Area) Area {
} }
} }
func (c *Channel) RequestDeleteAreaById(areaId string) bool {
documentOfArea := document.GetDocumentCollection().GetDocumentByAreaId(areaId)
if documentOfArea.Id == "" {
return false
}
areaToDeleteIndex := -1
for i, a := range documentOfArea.Areas {
if a.Id == areaId {
areaToDeleteIndex = i
break
}
}
if areaToDeleteIndex < 0 {
return false
}
// func remove(s []int, i int) []int {
// s[i] = s[len(s)-1]
// return s[:len(s)-1]
// }
documentOfArea.Areas[areaToDeleteIndex] = documentOfArea.Areas[len(documentOfArea.Areas)-1]
documentOfArea.Areas = documentOfArea.Areas[:len(documentOfArea.Areas)-1]
return true
}
func (c *Channel) RequestUpdateDocument(updatedDocument Document) Document { func (c *Channel) RequestUpdateDocument(updatedDocument Document) Document {
documentToUpdate := document.GetDocumentCollection().GetDocumentById(updatedDocument.Id) documentToUpdate := document.GetDocumentCollection().GetDocumentById(updatedDocument.Id)