several things
no longer using next app dir no selected document view top tab navigation
This commit is contained in:
parent
84d71ddc35
commit
fe25bc1c2e
@ -1,32 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>NSDocumentsFolderUsageDescription</key>
|
||||||
|
<string>To add your images to your project, textualize, and translate them.</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>Textualize</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>Textualize</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.wails.Textualize</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1.0.0</string>
|
||||||
|
<key>CFBundleGetInfoString</key>
|
||||||
|
<string>Built using Wails (https://wails.io)</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0.0</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>iconfile</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>10.13.0</string>
|
||||||
|
<key>NSHighResolutionCapable</key>
|
||||||
|
<string>true</string>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>Copyright.........</string>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundlePackageType</key>
|
<key>NSAllowsLocalNetworking</key>
|
||||||
<string>APPL</string>
|
<true/>
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>Textualize</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>Textualize</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>com.wails.Textualize</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>1.0.0</string>
|
|
||||||
<key>CFBundleGetInfoString</key>
|
|
||||||
<string>Built using Wails (https://wails.io)</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>1.0.0</string>
|
|
||||||
<key>CFBundleIconFile</key>
|
|
||||||
<string>iconfile</string>
|
|
||||||
<key>LSMinimumSystemVersion</key>
|
|
||||||
<string>10.13.0</string>
|
|
||||||
<key>NSHighResolutionCapable</key>
|
|
||||||
<string>true</string>
|
|
||||||
<key>NSHumanReadableCopyright</key>
|
|
||||||
<string>Copyright.........</string>
|
|
||||||
<key>NSAppTransportSecurity</key>
|
|
||||||
<dict>
|
|
||||||
<key>NSAllowsLocalNetworking</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
</dict>
|
||||||
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@ -1,32 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>NSDocumentsFolderUsageDescription</key>
|
||||||
|
<string>To add your images to your project, textualize, and translate them.</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>{{.Info.ProductName}}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>{{.Name}}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.wails.{{.Name}}</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>{{.Info.ProductVersion}}</string>
|
||||||
|
<key>CFBundleGetInfoString</key>
|
||||||
|
<string>{{.Info.Comments}}</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>{{.Info.ProductVersion}}</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>iconfile</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>10.13.0</string>
|
||||||
|
<key>NSHighResolutionCapable</key>
|
||||||
|
<string>true</string>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>{{.Info.Copyright}}</string>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundlePackageType</key>
|
<key>NSAllowsLocalNetworking</key>
|
||||||
<string>APPL</string>
|
<true/>
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>{{.Info.ProductName}}</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>{{.Name}}</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>com.wails.{{.Name}}</string>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>{{.Info.ProductVersion}}</string>
|
|
||||||
<key>CFBundleGetInfoString</key>
|
|
||||||
<string>{{.Info.Comments}}</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>{{.Info.ProductVersion}}</string>
|
|
||||||
<key>CFBundleIconFile</key>
|
|
||||||
<string>iconfile</string>
|
|
||||||
<key>LSMinimumSystemVersion</key>
|
|
||||||
<string>10.13.0</string>
|
|
||||||
<key>NSHighResolutionCapable</key>
|
|
||||||
<string>true</string>
|
|
||||||
<key>NSHumanReadableCopyright</key>
|
|
||||||
<string>{{.Info.Copyright}}</string>
|
|
||||||
<key>NSAppTransportSecurity</key>
|
|
||||||
<dict>
|
|
||||||
<key>NSAllowsLocalNetworking</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
</dict>
|
||||||
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@ -1,14 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0"><dict>
|
<plist version="1.0">
|
||||||
<key>CFBundlePackageType</key><string>APPL</string>
|
<dict>
|
||||||
<key>CFBundleName</key><string>{{.Info.ProductName}}</string>
|
<key>NSDocumentsFolderUsageDescription</key>
|
||||||
<key>CFBundleExecutable</key><string>{{.Name}}</string>
|
<string>Do it</string>
|
||||||
<key>CFBundleIdentifier</key><string>com.wails.{{.Name}}</string>
|
<key>CFBundlePackageType</key>
|
||||||
<key>CFBundleVersion</key><string>{{.Info.ProductVersion}}</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleGetInfoString</key><string>{{.Info.Comments}}</string>
|
<key>CFBundleName</key>
|
||||||
<key>CFBundleShortVersionString</key><string>{{.Info.ProductVersion}}</string>
|
<string>{{.Info.ProductName}}</string>
|
||||||
<key>CFBundleIconFile</key><string>iconfile</string>
|
<key>CFBundleExecutable</key>
|
||||||
<key>LSMinimumSystemVersion</key><string>10.13.0</string>
|
<string>{{.Name}}</string>
|
||||||
<key>NSHighResolutionCapable</key><string>true</string>
|
<key>CFBundleIdentifier</key>
|
||||||
<key>NSHumanReadableCopyright</key><string>{{.Info.Copyright}}</string>
|
<string>com.wails.{{.Name}}</string>
|
||||||
</dict></plist>
|
<key>CFBundleVersion</key>
|
||||||
|
<string>{{.Info.ProductVersion}}</string>
|
||||||
|
<key>CFBundleGetInfoString</key>
|
||||||
|
<string>{{.Info.Comments}}</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>{{.Info.ProductVersion}}</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>iconfile</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>10.13.0</string>
|
||||||
|
<key>NSHighResolutionCapable</key>
|
||||||
|
<string>true</string>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>{{.Info.Copyright}}</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"extends": "next/core-web-vitals",
|
"extends": "next/core-web-vitals",
|
||||||
"rules": {
|
"rules": {
|
||||||
"@next/next/no-img-element": "off"
|
"@next/next/no-img-element": "off",
|
||||||
|
"quotes": ["warn", "single"],
|
||||||
|
"semi": ["warn", "never"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import { ProjectProvider } from '../context/Project/provider'
|
|
||||||
import '../styles/globals.css'
|
|
||||||
import { ipc } from '../wailsjs/wailsjs/go/models'
|
|
||||||
|
|
||||||
type AppLayoutProps = {
|
|
||||||
children: React.ReactNode
|
|
||||||
}
|
|
||||||
|
|
||||||
const initialProjectProps = {
|
|
||||||
id: '',
|
|
||||||
documents: [] as ipc.Document[],
|
|
||||||
groups: [] as ipc.Group[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function MainAppLayout({ children }: AppLayoutProps) {
|
|
||||||
return <html className='bg-gray-100 bg-opacity-0'>
|
|
||||||
<body className='min-h-screen' >
|
|
||||||
<ProjectProvider projectProps={initialProjectProps}>
|
|
||||||
{children}
|
|
||||||
</ProjectProvider>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
}
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import Head from "next/head"
|
import Head from 'next/head'
|
||||||
|
|
||||||
const MainHead = () => <>
|
const MainHead = () => <>
|
||||||
<Head>
|
<Head>
|
||||||
@ -9,4 +9,4 @@ const MainHead = () => <>
|
|||||||
</Head>
|
</Head>
|
||||||
</>
|
</>
|
||||||
|
|
||||||
export default MainHead
|
export default MainHead
|
||||||
@ -1,91 +0,0 @@
|
|||||||
import { Menu, Transition } from "@headlessui/react"
|
|
||||||
import { MagnifyingGlassIcon } from "@heroicons/react/20/solid"
|
|
||||||
import { BellIcon } from "@heroicons/react/24/outline"
|
|
||||||
import { Fragment } from "react"
|
|
||||||
|
|
||||||
const userNavigation = [
|
|
||||||
{ name: 'Your Profile' },
|
|
||||||
{ name: 'Settings' },
|
|
||||||
{ name: 'Sign out' },
|
|
||||||
]
|
|
||||||
|
|
||||||
function classNames(...classes: any[]) {
|
|
||||||
return classes.filter(Boolean).join(' ')
|
|
||||||
}
|
|
||||||
|
|
||||||
const AppBar = () => <div className="flex flex-col md:pl-64">
|
|
||||||
<div className="sticky top-0 z-10 flex h-16 flex-shrink-0 bg-white shadow">
|
|
||||||
<div className="flex flex-1 justify-between px-4">
|
|
||||||
<div className="flex flex-1">
|
|
||||||
<form className="flex w-full md:ml-0" action="#" method="GET">
|
|
||||||
<label htmlFor="search-field" className="sr-only">
|
|
||||||
Search
|
|
||||||
</label>
|
|
||||||
<div className="relative w-full text-gray-400 focus-within:text-gray-600">
|
|
||||||
<div className="pointer-events-none absolute inset-y-0 left-0 flex items-center">
|
|
||||||
<MagnifyingGlassIcon className="h-5 w-5" aria-hidden="true" />
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
id="search-field"
|
|
||||||
className="block h-full w-full border-transparent py-2 pl-8 pr-3 text-gray-900 placeholder-gray-500 focus:border-transparent focus:placeholder-gray-400 focus:outline-none focus:ring-0 sm:text-sm"
|
|
||||||
placeholder="Search"
|
|
||||||
type="search"
|
|
||||||
name="search"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div className="ml-4 flex items-center md:ml-6">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="rounded-full bg-white p-1 text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
|
||||||
>
|
|
||||||
<span className="sr-only">View notifications</span>
|
|
||||||
<BellIcon className="h-6 w-6" aria-hidden="true" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Profile dropdown */}
|
|
||||||
<Menu as="div" className="relative ml-3">
|
|
||||||
<div>
|
|
||||||
<Menu.Button className="flex max-w-xs items-center rounded-full bg-white text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
|
|
||||||
<span className="sr-only">Open user menu</span>
|
|
||||||
<img
|
|
||||||
className="h-8 w-8 rounded-full"
|
|
||||||
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</Menu.Button>
|
|
||||||
</div>
|
|
||||||
<Transition
|
|
||||||
as={Fragment}
|
|
||||||
enter="transition ease-out duration-100"
|
|
||||||
enterFrom="transform opacity-0 scale-95"
|
|
||||||
enterTo="transform opacity-100 scale-100"
|
|
||||||
leave="transition ease-in duration-75"
|
|
||||||
leaveFrom="transform opacity-100 scale-100"
|
|
||||||
leaveTo="transform opacity-0 scale-95"
|
|
||||||
>
|
|
||||||
<Menu.Items className="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
|
|
||||||
{userNavigation.map((item) => (
|
|
||||||
<Menu.Item key={item.name}>
|
|
||||||
{({ active }) => (
|
|
||||||
<a
|
|
||||||
className={classNames(
|
|
||||||
active ? 'bg-gray-100' : '',
|
|
||||||
'block px-4 py-2 text-sm text-gray-700'
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{item.name}
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</Menu.Item>
|
|
||||||
))}
|
|
||||||
</Menu.Items>
|
|
||||||
</Transition>
|
|
||||||
</Menu>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
export default AppBar
|
|
||||||
@ -1,17 +1,9 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import React, { useEffect, useRef } from "react"
|
import React, { useEffect, useRef } from 'react'
|
||||||
import { useProject } from "../../context/Project/provider"
|
import { useProject } from '../../context/Project/provider'
|
||||||
import processImageData from "../../useCases/processImageData"
|
import loadImage from '../../useCases/loadImage'
|
||||||
|
import processImageData from '../../useCases/processImageData'
|
||||||
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 DocumentRenderer = () => {
|
||||||
const { getSelectedDocument, requestAddArea } = useProject()
|
const { getSelectedDocument, requestAddArea } = useProject()
|
||||||
@ -43,7 +35,13 @@ const DocumentRenderer = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const applyDocumentToCanvas = async (path: string) => {
|
const applyDocumentToCanvas = async (path: string) => {
|
||||||
const image = await loadImage(path)
|
let image: HTMLImageElement
|
||||||
|
try {
|
||||||
|
image = await loadImage(path)
|
||||||
|
} catch (err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
applyCanvasSizes({ width: image.naturalWidth, height: image.naturalHeight })
|
applyCanvasSizes({ width: image.naturalWidth, height: image.naturalHeight })
|
||||||
|
|
||||||
const documentCanvasInstance = documentCanvas.current
|
const documentCanvasInstance = documentCanvas.current
|
||||||
@ -57,14 +55,15 @@ const DocumentRenderer = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const applyAreasToCanvas = () => {
|
const applyAreasToCanvas = () => {
|
||||||
if (!areas || !areas.length) return
|
|
||||||
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)
|
||||||
|
|
||||||
|
if (!areas || !areas.length) return
|
||||||
|
|
||||||
areas.forEach(a => {
|
areas.forEach(a => {
|
||||||
const width = a.endX - a.startX
|
const width = a.endX - a.startX
|
||||||
const height = a.endY - a.startY
|
const height = a.endY - a.startY
|
||||||
@ -113,8 +112,9 @@ const DocumentRenderer = () => {
|
|||||||
|
|
||||||
if (selectedDocument?.id) {
|
if (selectedDocument?.id) {
|
||||||
await requestAddArea(selectedDocument.id, { startX, startY, endX, endY })
|
await requestAddArea(selectedDocument.id, { startX, startY, endX, endY })
|
||||||
const results = await processImageData(selectedDocument.id)
|
processImageData(selectedDocument.id).then(results => {
|
||||||
console.log(results)
|
console.log(results)
|
||||||
|
}).catch(err => console.log(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
const context = drawingCanvasInstance.getContext('2d')
|
const context = drawingCanvasInstance.getContext('2d')
|
||||||
@ -156,15 +156,15 @@ const DocumentRenderer = () => {
|
|||||||
|
|
||||||
return <div className="relative">
|
return <div className="relative">
|
||||||
<canvas
|
<canvas
|
||||||
className="absolute"
|
className="absolute border-4 border-dashed border-gray-200"
|
||||||
ref={documentCanvas}
|
ref={documentCanvas}
|
||||||
/>
|
/>
|
||||||
<canvas
|
<canvas
|
||||||
className="absolute"
|
className="absolute border-4 border-transparent"
|
||||||
ref={areaCanvas}
|
ref={areaCanvas}
|
||||||
/>
|
/>
|
||||||
<canvas
|
<canvas
|
||||||
className="absolute"
|
className="absolute border-4 border-transparent"
|
||||||
ref={drawingCanvas}
|
ref={drawingCanvas}
|
||||||
onMouseDown={handleMouseDown}
|
onMouseDown={handleMouseDown}
|
||||||
onMouseUp={handleMouseUp}
|
onMouseUp={handleMouseUp}
|
||||||
|
|||||||
@ -1,24 +1,27 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useProject } from "../../context/Project/provider"
|
import { useProject } from '../../context/Project/provider'
|
||||||
import DocumentRenderer from "./DocumentRenderer"
|
import DocumentRenderer from './DocumentRenderer'
|
||||||
|
import NoSelectedDocument from './NoSelectedDocument'
|
||||||
|
|
||||||
const MainWorkspace = () => {
|
const MainWorkspace = () => {
|
||||||
const { getSelectedDocument } = useProject()
|
const { getSelectedDocument, selectedDocumentId } = useProject()
|
||||||
|
|
||||||
|
|
||||||
return <main className=" bg-gray-100 min-h-[calc(100vh-4rem)] ml-64 ">
|
return <main className=" bg-gray-100 min-h-[calc(100vh-118px)] ml-64 overflow-y-scroll">
|
||||||
<div className='flex-1'>
|
<div className='flex-1'>
|
||||||
<div className="py-6">
|
<div className="py-1">
|
||||||
<div className="mx-auto px-4 sm:px-6 md:px-8">
|
|
||||||
<h1 className="text-2xl font-semibold text-gray-900">
|
|
||||||
{ getSelectedDocument()?.name }
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<div className="mx-auto px-4 sm:px-6 md:px-8">
|
<div className="mx-auto px-4 sm:px-6 md:px-8">
|
||||||
<div className="py-4">
|
<div className="py-2">
|
||||||
<div className=" min-h-96 border-4 border-dashed border-gray-200">
|
<div className="mx-auto px-4 sm:px-6 md:px-8">
|
||||||
<DocumentRenderer />
|
<h1 className="text-2xl font-semibold text-gray-900">
|
||||||
|
{getSelectedDocument()?.name || 'Image Processor'}
|
||||||
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
{!selectedDocumentId
|
||||||
|
? <NoSelectedDocument />
|
||||||
|
: <DocumentRenderer />
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,16 +1,14 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import React, { useRef, useState } from 'react'
|
|
||||||
import { PlusIcon, XMarkIcon } from '@heroicons/react/20/solid'
|
|
||||||
import AppBar from './AppBar'
|
|
||||||
import Sidebar from './Sidebar'
|
import Sidebar from './Sidebar'
|
||||||
|
import TopBar from './TopBar'
|
||||||
|
|
||||||
function WorkspaceNavigation() {
|
function WorkspaceNavigation() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<TopBar />
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
<AppBar />
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
22
frontend/components/workspace/NoSelectedDocument.tsx
Normal file
22
frontend/components/workspace/NoSelectedDocument.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { DocumentPlusIcon } from '@heroicons/react/24/outline'
|
||||||
|
|
||||||
|
export default function NoSelectedDocument() {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="relative block w-full rounded-lg border-4 border-dashed border-gray-200 p-12 text-center hover:border-gray-400 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
className="mx-auto h-12 w-12 text-gray-400"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 48 48"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<DocumentPlusIcon />
|
||||||
|
</svg>
|
||||||
|
<span className="mt-2 block text-sm font-medium text-gray-900">Add Document</span>
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
89
frontend/components/workspace/Search.tsx
Normal file
89
frontend/components/workspace/Search.tsx
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import { Menu, Transition } from '@headlessui/react'
|
||||||
|
import { MagnifyingGlassIcon } from '@heroicons/react/20/solid'
|
||||||
|
import { BellIcon } from '@heroicons/react/24/outline'
|
||||||
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
|
const userNavigation = [
|
||||||
|
{ name: 'Your Profile' },
|
||||||
|
{ name: 'Settings' },
|
||||||
|
{ name: 'Sign out' },
|
||||||
|
]
|
||||||
|
|
||||||
|
function classNames(...classes: any[]) {
|
||||||
|
return classes.filter(Boolean).join(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
const Search = () => <div className="top-0 z-10 flex h-16 flex-shrink-0 bg-white">
|
||||||
|
<div className="flex flex-1 justify-between px-4">
|
||||||
|
<div className="flex flex-1">
|
||||||
|
<form className="flex w-full md:ml-0" action="#" method="GET">
|
||||||
|
<label htmlFor="search-field" className="sr-only">
|
||||||
|
Search
|
||||||
|
</label>
|
||||||
|
<div className="relative w-full text-gray-400 focus-within:text-gray-600">
|
||||||
|
<div className="pointer-events-none absolute inset-y-0 left-0 flex items-center">
|
||||||
|
<MagnifyingGlassIcon className="h-5 w-5" aria-hidden="true" />
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
id="search-field"
|
||||||
|
className="block h-full w-full border-transparent py-2 pl-8 pr-3 text-gray-900 placeholder-gray-500 focus:border-transparent focus:placeholder-gray-400 focus:outline-none focus:ring-0 sm:text-sm"
|
||||||
|
placeholder="Search"
|
||||||
|
type="search"
|
||||||
|
name="search"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div className="ml-4 flex items-center md:ml-6">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="rounded-full bg-white p-1 text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||||
|
>
|
||||||
|
<span className="sr-only">View notifications</span>
|
||||||
|
<BellIcon className="h-6 w-6" aria-hidden="true" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Profile dropdown */}
|
||||||
|
<Menu as="div" className="relative ml-3">
|
||||||
|
<div>
|
||||||
|
<Menu.Button className="flex max-w-xs items-center rounded-full bg-white text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
|
||||||
|
<span className="sr-only">Open user menu</span>
|
||||||
|
<img
|
||||||
|
className="h-8 w-8 rounded-full"
|
||||||
|
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</Menu.Button>
|
||||||
|
</div>
|
||||||
|
<Transition
|
||||||
|
as={Fragment}
|
||||||
|
enter="transition ease-out duration-100"
|
||||||
|
enterFrom="transform opacity-0 scale-95"
|
||||||
|
enterTo="transform opacity-100 scale-100"
|
||||||
|
leave="transition ease-in duration-75"
|
||||||
|
leaveFrom="transform opacity-100 scale-100"
|
||||||
|
leaveTo="transform opacity-0 scale-95"
|
||||||
|
>
|
||||||
|
<Menu.Items className="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
|
||||||
|
{userNavigation.map((item) => (
|
||||||
|
<Menu.Item key={item.name}>
|
||||||
|
{({ active }) => (
|
||||||
|
<a
|
||||||
|
className={classNames(
|
||||||
|
active ? 'bg-gray-100' : '',
|
||||||
|
'block px-4 py-2 text-sm text-gray-700'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{item.name}
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</Menu.Item>
|
||||||
|
))}
|
||||||
|
</Menu.Items>
|
||||||
|
</Transition>
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
export default Search
|
||||||
44
frontend/components/workspace/ToolTabs.tsx
Normal file
44
frontend/components/workspace/ToolTabs.tsx
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
|
|
||||||
|
const tabs = [
|
||||||
|
{ name: 'Processor', id: 0 },
|
||||||
|
{ name: 'Text Editor', id: 1 },
|
||||||
|
{ name: 'Translator', id: 2 },
|
||||||
|
{ name: 'Details', id: 3 },
|
||||||
|
]
|
||||||
|
|
||||||
|
function classNames(...classes: string[]) {
|
||||||
|
return classes.filter(Boolean).join(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ToolTabs() {
|
||||||
|
const [selectedTabId, setSelectedTabId] = useState(0)
|
||||||
|
|
||||||
|
const getIsSelectedTab = (tabId: number) => tabId === selectedTabId
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-white shadow">
|
||||||
|
<div className="hidden sm:block">
|
||||||
|
<div className="border-b border-gray-200">
|
||||||
|
<nav className="-mb-px flex" aria-label="Tabs">
|
||||||
|
{tabs.map((tab) => (
|
||||||
|
<a
|
||||||
|
key={tab.name}
|
||||||
|
onClick={_ => setSelectedTabId(tab.id)}
|
||||||
|
className={classNames(
|
||||||
|
getIsSelectedTab(tab.id)
|
||||||
|
? 'border-indigo-500 text-indigo-600'
|
||||||
|
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300',
|
||||||
|
'cursor-pointer w-1/4 py-4 px-1 text-center border-b-2 font-medium text-sm'
|
||||||
|
)}
|
||||||
|
aria-current={getIsSelectedTab(tab.id) ? 'page' : undefined}
|
||||||
|
>
|
||||||
|
{tab.name}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
9
frontend/components/workspace/TopBar.tsx
Normal file
9
frontend/components/workspace/TopBar.tsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import Search from './Search'
|
||||||
|
import ToolTabs from './ToolTabs'
|
||||||
|
|
||||||
|
const TopBar = () => <div className="flex flex-col md:pl-64 sticky">
|
||||||
|
<Search />
|
||||||
|
<ToolTabs />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
export default TopBar
|
||||||
@ -1,12 +1,16 @@
|
|||||||
import { ipc } from "../../wailsjs/wailsjs/go/models"
|
import { ipc } from '../../wailsjs/wailsjs/go/models'
|
||||||
import { ProjectContextType } from "./types"
|
import { ProjectContextType } from './types'
|
||||||
|
|
||||||
const makeDefaultProject = (): ProjectContextType => ({
|
const makeDefaultProject = (): ProjectContextType => ({
|
||||||
id: '',
|
id: '',
|
||||||
documents: [] as ipc.Document[],
|
documents: [] as ipc.Document[],
|
||||||
groups: [] as ipc.Group[],
|
groups: [] as ipc.Group[],
|
||||||
requestAddDocument: (groupId: string, documentName: string) => Promise.resolve(new ipc.Document()),
|
selectedDocumentId: '',
|
||||||
requestAddDocumentGroup: (groupName: string) => Promise.resolve(new ipc.Group())
|
getSelectedDocument: () => new ipc.Document(),
|
||||||
|
requestAddArea: (documentId, area) => Promise.resolve(new ipc.Area()),
|
||||||
|
requestAddDocument: (groupId, documentName) => Promise.resolve(new ipc.Document()),
|
||||||
|
requestAddDocumentGroup: (groupName: string) => Promise.resolve(new ipc.Group()),
|
||||||
|
setSelectedDocumentId: (id) => {}
|
||||||
})
|
})
|
||||||
|
|
||||||
export default makeDefaultProject
|
export default makeDefaultProject
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import { createContext, ReactNode, useContext, useState } from 'react'
|
'use client'
|
||||||
|
|
||||||
|
import { createContext, ReactNode, useContext, useEffect, useState } from 'react'
|
||||||
import { GetDocuments, RequestAddArea, RequestAddDocument, RequestAddDocumentGroup } from '../../wailsjs/wailsjs/go/ipc/Channel'
|
import { GetDocuments, RequestAddArea, RequestAddDocument, RequestAddDocumentGroup } from '../../wailsjs/wailsjs/go/ipc/Channel'
|
||||||
import { ipc } from '../../wailsjs/wailsjs/go/models'
|
import { ipc } from '../../wailsjs/wailsjs/go/models'
|
||||||
import { AddAreaProps, ProjectContextType, ProjectProps } from './types'
|
import { AddAreaProps, ProjectContextType, ProjectProps } from './types'
|
||||||
import makeDefaultProject from './makeDefaultProject'
|
import makeDefaultProject from './makeDefaultProject'
|
||||||
import { LogPrint } from '../../wailsjs/wailsjs/runtime/runtime'
|
|
||||||
|
|
||||||
const ProjectContext = createContext<ProjectContextType>(makeDefaultProject())
|
const ProjectContext = createContext<ProjectContextType>(makeDefaultProject())
|
||||||
|
|
||||||
@ -46,7 +47,9 @@ export function ProjectProvider({ children, projectProps }: Props) {
|
|||||||
|
|
||||||
const getSelectedDocument = () => documents.find(d => d.id === selectedDocumentId)
|
const getSelectedDocument = () => documents.find(d => d.id === selectedDocumentId)
|
||||||
|
|
||||||
if (!documents.length && !groups.length) updateDocuments()
|
useEffect(() => {
|
||||||
|
if (!documents.length && !groups.length) updateDocuments()
|
||||||
|
}, [documents.length, groups.length])
|
||||||
|
|
||||||
const value = {
|
const value = {
|
||||||
id: '',
|
id: '',
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { ipc } from "../../wailsjs/wailsjs/go/models"
|
import { ipc } from '../../wailsjs/wailsjs/go/models'
|
||||||
|
|
||||||
export type ProjectProps = {
|
export type ProjectProps = {
|
||||||
id: string,
|
id: string,
|
||||||
|
|||||||
@ -6,8 +6,6 @@ const nextConfig = {
|
|||||||
// running `wails dev`, so we need to turn off Next.js' gzip compression.
|
// running `wails dev`, so we need to turn off Next.js' gzip compression.
|
||||||
// See <https://nextjs.org/docs/api-reference/next.config.js/compression>.
|
// See <https://nextjs.org/docs/api-reference/next.config.js/compression>.
|
||||||
compress: false,
|
compress: false,
|
||||||
swcMinify: true,
|
|
||||||
experimental: { appDir: true },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = nextConfig
|
module.exports = nextConfig
|
||||||
|
|||||||
925
frontend/package-lock.json
generated
925
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -16,23 +16,24 @@
|
|||||||
"@headlessui/react": "^1.7.4",
|
"@headlessui/react": "^1.7.4",
|
||||||
"@heroicons/react": "^2.0.13",
|
"@heroicons/react": "^2.0.13",
|
||||||
"@tailwindcss/forms": "^0.5.3",
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
"next": "^13.0.5",
|
"next": "^13.1.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"tesseract.js": "^4.0.2",
|
"tesseract.js": "^4.0.2",
|
||||||
"uuid": "^9.0.0"
|
"uuid": "^9.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^18.11.9",
|
"@types/node": "^18.11.18",
|
||||||
"@types/react": "^18.0.25",
|
"@types/react": "^18.0.26",
|
||||||
"@types/react-dom": "^18.0.9",
|
"@types/react-dom": "^18.0.10",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
"autoprefixer": "^10.4.13",
|
"autoprefixer": "^10.4.13",
|
||||||
"eslint": "^8.28.0",
|
"encoding": "^0.1.13",
|
||||||
"eslint-config-next": "^13.0.5",
|
"eslint": "^8.30.0",
|
||||||
|
"eslint-config-next": "^13.1.1",
|
||||||
"postcss": "^8.4.19",
|
"postcss": "^8.4.19",
|
||||||
"server-only": "^0.0.1",
|
"server-only": "^0.0.1",
|
||||||
"tailwindcss": "^3.2.4",
|
"tailwindcss": "^3.2.4",
|
||||||
"typescript": "^4.9.3"
|
"typescript": "^4.9.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
05ad3a0ab3e3a8a6f053da2615d0270f
|
181c6c1e8f906e05414ee1ebe8117fcb
|
||||||
21
frontend/pages/_app.tsx
Normal file
21
frontend/pages/_app.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { AppProps } from 'next/app'
|
||||||
|
import { ProjectProvider } from '../context/Project/provider'
|
||||||
|
import '../styles/globals.css'
|
||||||
|
import { ipc } from '../wailsjs/wailsjs/go/models'
|
||||||
|
import '../styles/globals.css'
|
||||||
|
|
||||||
|
const initialProjectProps = {
|
||||||
|
id: '',
|
||||||
|
documents: [] as ipc.Document[],
|
||||||
|
groups: [] as ipc.Group[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function MainAppLayout({ Component, pageProps }: AppProps) {
|
||||||
|
return <div className='min-h-screen' >
|
||||||
|
<ProjectProvider projectProps={initialProjectProps}>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</ProjectProvider>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@ -1,9 +1,9 @@
|
|||||||
import 'server-only'
|
import { NextPage } from 'next'
|
||||||
import MainHead from '../components/MainHead'
|
import MainHead from '../components/head'
|
||||||
import MainWorkspace from '../components/workspace/Main'
|
import MainWorkspace from '../components/workspace/Main'
|
||||||
import Navigation from '../components/workspace/Navigation'
|
import Navigation from '../components/workspace/Navigation'
|
||||||
|
|
||||||
export default function Home() {
|
const Home: NextPage = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MainHead />
|
<MainHead />
|
||||||
@ -12,3 +12,6 @@ export default function Home() {
|
|||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default Home
|
||||||
|
|
||||||
@ -6,7 +6,7 @@ html,
|
|||||||
body {
|
body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-color: rgba(0, 0, 0, 0);
|
background-color: rgb(243 244 246 / 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
|||||||
@ -1,9 +1,14 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
const loadImage = (path: string): Promise<HTMLImageElement> => {
|
const loadImage = (path: string): Promise<HTMLImageElement> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const image = new Image()
|
const image = new Image()
|
||||||
image.src = path
|
image.src = path
|
||||||
image.onload = () => resolve(image)
|
image.onload = () => resolve(image)
|
||||||
image.onerror = (error) => reject(error)
|
image.onerror = (error) => {
|
||||||
|
console.log(error)
|
||||||
|
reject(error)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,26 +1,6 @@
|
|||||||
import { createScheduler, createWorker } from "tesseract.js"
|
import { createScheduler, createWorker } from 'tesseract.js'
|
||||||
import { GetDocumentById } from "../wailsjs/wailsjs/go/ipc/Channel"
|
import { GetDocumentById } from '../wailsjs/wailsjs/go/ipc/Channel'
|
||||||
import { ipc } from "../wailsjs/wailsjs/go/models"
|
import loadImage from './loadImage'
|
||||||
import loadImage from "./loadImage"
|
|
||||||
|
|
||||||
const getBase64 = (imageData: ImageData) => {
|
|
||||||
const canvasOfSection = document.createElement('canvas')
|
|
||||||
canvasOfSection.width = imageData.width
|
|
||||||
canvasOfSection.height = imageData.height
|
|
||||||
canvasOfSection.getContext('2d')!.putImageData(imageData, 0, 0)
|
|
||||||
return canvasOfSection.toDataURL()
|
|
||||||
}
|
|
||||||
|
|
||||||
const getImageContextFromDocument = async (doc: ipc.Document) => {
|
|
||||||
const image = await loadImage(doc.path)
|
|
||||||
const canvas = document.createElement('canvas')
|
|
||||||
canvas.width = image.naturalWidth
|
|
||||||
canvas.height = image.height
|
|
||||||
|
|
||||||
const context = canvas.getContext('2d')!
|
|
||||||
context?.drawImage(image, 0, 0, image.width, image.height)
|
|
||||||
return context
|
|
||||||
}
|
|
||||||
|
|
||||||
const getImageWorkerCount = (areaCount: number) => {
|
const getImageWorkerCount = (areaCount: number) => {
|
||||||
const minWorkerCount = 1
|
const minWorkerCount = 1
|
||||||
@ -28,21 +8,8 @@ const getImageWorkerCount = (areaCount: number) => {
|
|||||||
const areasPerWorker = 10
|
const areasPerWorker = 10
|
||||||
|
|
||||||
if (areaCount > maxWorkerCount * areasPerWorker) return maxWorkerCount;
|
if (areaCount > maxWorkerCount * areasPerWorker) return maxWorkerCount;
|
||||||
if (areaCount <= areasPerWorker) return 1
|
if (areaCount <= areasPerWorker) return minWorkerCount
|
||||||
|
return ~~(areaCount / areasPerWorker)
|
||||||
const workerCount = ~~(areaCount / areasPerWorker)
|
|
||||||
return workerCount
|
|
||||||
}
|
|
||||||
|
|
||||||
const getImageData = async (path: string) => {
|
|
||||||
const image = await loadImage(path)
|
|
||||||
const canvas = document.createElement('canvas')
|
|
||||||
canvas.width = image.naturalWidth
|
|
||||||
canvas.height = image.height
|
|
||||||
|
|
||||||
const context = canvas.getContext('2d')!
|
|
||||||
context?.drawImage(image, 0, 0, image.width, image.height)
|
|
||||||
return canvas.toDataURL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const processImageData = async (documentId: string) => {
|
const processImageData = async (documentId: string) => {
|
||||||
@ -51,6 +18,8 @@ const processImageData = async (documentId: string) => {
|
|||||||
|
|
||||||
const { areas, path } = foundDocument
|
const { areas, path } = foundDocument
|
||||||
|
|
||||||
|
console.log(`about to load: ${path}`)
|
||||||
|
|
||||||
const imageData = await loadImage(path)
|
const imageData = await loadImage(path)
|
||||||
|
|
||||||
const scheduler = createScheduler()
|
const scheduler = createScheduler()
|
||||||
@ -66,19 +35,12 @@ const processImageData = async (documentId: string) => {
|
|||||||
|
|
||||||
const results = await Promise.allSettled(areas.map(a => {
|
const results = await Promise.allSettled(areas.map(a => {
|
||||||
console.log('adding job')
|
console.log('adding job')
|
||||||
// TODO: for some reason the entire image is being recognized
|
return scheduler.addJob('recognize', imageData, { rectangle: {
|
||||||
console.log({
|
|
||||||
left: a.startX,
|
left: a.startX,
|
||||||
top: a.startY,
|
top: a.startY,
|
||||||
width: a.endX - a.startX,
|
width: a.endX - a.startX,
|
||||||
height: a.endY - a.startY,
|
height: a.endY - a.startY,
|
||||||
})
|
}})
|
||||||
return scheduler.addJob('recognize', imageData, {
|
|
||||||
left: a.startX,
|
|
||||||
top: a.startY,
|
|
||||||
width: a.endX - a.startX,
|
|
||||||
height: a.endY - a.startY,
|
|
||||||
})
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|||||||
@ -93,6 +93,10 @@ export function WindowReload(): void;
|
|||||||
// Reloads the application frontend.
|
// Reloads the application frontend.
|
||||||
export function WindowReloadApp(): void;
|
export function WindowReloadApp(): void;
|
||||||
|
|
||||||
|
// [WindowSetAlwaysOnTop](https://wails.io/docs/reference/runtime/window#windowsetalwaysontop)
|
||||||
|
// Sets the window AlwaysOnTop or not on top.
|
||||||
|
export function WindowSetAlwaysOnTop(b: boolean): void;
|
||||||
|
|
||||||
// [WindowSetSystemDefaultTheme](https://wails.io/docs/next/reference/runtime/window#windowsetsystemdefaulttheme)
|
// [WindowSetSystemDefaultTheme](https://wails.io/docs/next/reference/runtime/window#windowsetsystemdefaulttheme)
|
||||||
// *Windows only*
|
// *Windows only*
|
||||||
// Sets window theme to system default (dark/light).
|
// Sets window theme to system default (dark/light).
|
||||||
|
|||||||
@ -65,6 +65,10 @@ export function WindowReloadApp() {
|
|||||||
window.runtime.WindowReloadApp();
|
window.runtime.WindowReloadApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function WindowSetAlwaysOnTop(b) {
|
||||||
|
window.runtime.WindowSetAlwaysOnTop(b);
|
||||||
|
}
|
||||||
|
|
||||||
export function WindowSetSystemDefaultTheme() {
|
export function WindowSetSystemDefaultTheme() {
|
||||||
window.runtime.WindowSetSystemDefaultTheme();
|
window.runtime.WindowSetSystemDefaultTheme();
|
||||||
}
|
}
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -6,7 +6,7 @@ go 1.18
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/wailsapp/wails/v2 v2.2.0
|
github.com/wailsapp/wails/v2 v2.3.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
4
go.sum
4
go.sum
@ -52,8 +52,8 @@ github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52
|
|||||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||||
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
||||||
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
||||||
github.com/wailsapp/wails/v2 v2.2.0 h1:+zRTNjwqyz1kofT0J2R1FpxXB+m3cZJzW3RjxDgxWNw=
|
github.com/wailsapp/wails/v2 v2.3.1 h1:ZJz+pyIBKyASkgO8JO31NuHO1gTTHmvwiHYHwei1CqM=
|
||||||
github.com/wailsapp/wails/v2 v2.2.0/go.mod h1:zdc9YVrIijjuNNkLOO3UpTU6M12TJe6TlriL+3ttlMM=
|
github.com/wailsapp/wails/v2 v2.3.1/go.mod h1:zlNLI0E2c2qA6miiuAHtp0Bac8FaGH0tlhA19OssR/8=
|
||||||
golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
|
golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
|
||||||
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
|
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
|
||||||
golang.org/x/exp v0.0.0-20221207211629-99ab8fa1c11f h1:90Jq/vvGVDsqj8QqCynjFw9MCerDguSMODLYII416Y8=
|
golang.org/x/exp v0.0.0-20221207211629-99ab8fa1c11f h1:90Jq/vvGVDsqj8QqCynjFw9MCerDguSMODLYII416Y8=
|
||||||
|
|||||||
10
main.go
10
main.go
@ -19,7 +19,7 @@ import (
|
|||||||
"github.com/wailsapp/wails/v2/pkg/options/windows"
|
"github.com/wailsapp/wails/v2/pkg/options/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed frontend/out frontend/out/_next/static
|
//go:embed all:frontend/out frontend/out/_next/static/*/* frontend/out/_next/static/*/*/*
|
||||||
var assets embed.FS
|
var assets embed.FS
|
||||||
|
|
||||||
type FileLoader struct {
|
type FileLoader struct {
|
||||||
@ -32,9 +32,14 @@ func ClientFileLoader() *FileLoader {
|
|||||||
|
|
||||||
func (h *FileLoader) ServeHTTP(res http.ResponseWriter, req *http.Request) {
|
func (h *FileLoader) ServeHTTP(res http.ResponseWriter, req *http.Request) {
|
||||||
var err error
|
var err error
|
||||||
|
// Make sure to prefix all local files with this in renderer
|
||||||
|
// requestedFilename := strings.TrimPrefix(req.URL.Path, "/textualizeFileAssets")
|
||||||
requestedFilename := req.URL.Path
|
requestedFilename := req.URL.Path
|
||||||
|
fmt.Println(requestedFilename)
|
||||||
fileData, err := os.ReadFile(requestedFilename)
|
fileData, err := os.ReadFile(requestedFilename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Println("was eror: ")
|
||||||
|
fmt.Println(err)
|
||||||
res.WriteHeader(http.StatusBadRequest)
|
res.WriteHeader(http.StatusBadRequest)
|
||||||
res.Write([]byte(fmt.Sprintf("Could not load file %s", requestedFilename)))
|
res.Write([]byte(fmt.Sprintf("Could not load file %s", requestedFilename)))
|
||||||
}
|
}
|
||||||
@ -71,6 +76,9 @@ func main() {
|
|||||||
Assets: assets,
|
Assets: assets,
|
||||||
Handler: ClientFileLoader(),
|
Handler: ClientFileLoader(),
|
||||||
},
|
},
|
||||||
|
Debug: options.Debug{
|
||||||
|
OpenInspectorOnStartup: true,
|
||||||
|
},
|
||||||
Menu: nil,
|
Menu: nil,
|
||||||
Logger: nil,
|
Logger: nil,
|
||||||
LogLevel: logger.DEBUG,
|
LogLevel: logger.DEBUG,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user