From 11cd6630fb78643469f20b5c446936d941d11529 Mon Sep 17 00:00:00 2001 From: Stu Leak Date: Sun, 4 Jan 2026 05:09:32 -0500 Subject: [PATCH] Commit pending assets, deps, and enhancement fixes --- WORKING_ON.md | 135 +++-- assets/logo/LT_Logo-26.png | Bin 0 -> 30740 bytes assets/logo/VT_Prototype.svg | 639 --------------------- go.mod | 4 +- go.sum | 18 + internal/enhancement/enhancement_module.go | 46 +- internal/enhancement/onnx_model.go | 1 - main.go | 7 + qr-demo/go.mod | 8 + qr-demo/go.sum | 4 + qr-demo/qr_about_demo.go | 99 ++++ 11 files changed, 233 insertions(+), 728 deletions(-) create mode 100644 assets/logo/LT_Logo-26.png delete mode 100644 assets/logo/VT_Prototype.svg create mode 100644 qr-demo/go.mod create mode 100644 qr-demo/go.sum create mode 100644 qr-demo/qr_about_demo.go diff --git a/WORKING_ON.md b/WORKING_ON.md index b192628..a73e584 100644 --- a/WORKING_ON.md +++ b/WORKING_ON.md @@ -2,100 +2,111 @@ This file tracks what each agent is currently working on to prevent conflicts and coordinate changes. -**Last Updated**: 2026-01-04 02:30 UTC +**Last Updated**: 2026-01-04 10:00 UTC --- ## 🔴 Current Blockers -- **Build Status**: ✅ PASSING (dev23 UI cleanup complete) +- **Build Status**: ⚠️ NEARLY PASSING - 3 compilation errors remain (lines 500, 6995-7003 in main.go) --- ## 👥 Active Work by Agent ### 🤖 Claude (thisagent - Claude Code) -**Status**: ✅ DEV23 COMPLETE - v0.1.0-dev23 ready +**Status**: ⚠️ IN PROGRESS - Widget deduplication + compilation fixes -**Completed This Session** (2026-01-04): -- ✅ Refined colored dropdowns (accent bar, rounded corners, improved legibility) -- ✅ Aligned settings panel input backgrounds to dropdown tone -- ✅ Styled Auto-Crop and Interlacing actions to match panel UI -- ✅ Rebuilt About / Support dialog to match mockup -- ✅ Fixed Audio module crash on initial quality select -- ✅ Bumped version to v0.1.0-dev23 +**Completed This Session** (2026-01-04 10:00): +- ✅ **Quality Widget Deduplication** (main.go:7075-7128) + - Converted qualitySelectSimple/Adv to ColoredSelect + - Registered both with state manager for auto-sync + - Updated updateQualityOptions to use state manager + - Eliminated manual synchronization code +- ✅ **Enhancement Module Fixes** (internal/enhancement/) + - Defined SkinToneAnalysis struct + - Fixed invalid ContentAnalysis field assignments + - Removed unused imports and variables + - Fixed onnx_model.go unused variable +- ✅ **Missing Imports Restored** (main.go:3-48) + - Added: atomic, json, sort, io, errors, bufio, strconv, math + - Added: fyne.io/fyne/v2/driver/desktop + - Added: internal/interlace, internal/sysinfo + - Added: github.com/ebitengine/oto/v3 +- ✅ **Code Cleanup** + - Removed duplicate QR code function **Files Modified**: -- `main.go` - About dialog layout, UI polish, audio crash fix, version bump -- `internal/ui/components.go` - Colored select styling + input background tone -- `FyneApp.toml` - Version bump to dev23 -- `docs/CHANGELOG.md` - Dev23 release notes +- `main.go` - Quality widget deduplication, missing imports, duplicate code removal +- `internal/enhancement/enhancement_module.go` - SkinToneAnalysis struct, field fixes +- `internal/enhancement/onnx_model.go` - Unused variable cleanup +- `go.mod`, `go.sum` - Added oto/v3 dependency -**Next Tasks**: -1. Update docs to dev23 (ROADMAP/TODO/WORKING_ON/DONE) -2. Create git tag v0.1.0-dev23 -3. Begin dev24 planning with Jake +**⚠️ Remaining Compilation Errors** (HANDOFF TO opencode): +1. Line 500: `canvas.NewImageFromBytes` undefined - QR code generation +2. Lines 6995-7003: `outputExtLabel`, `outputExtBG`, `updateOutputHint` undefined - Convert UI + +**Next Tasks for opencode**: +1. Fix 3 remaining compilation errors in main.go +2. Continue widget deduplication (4 remaining pairs) +3. Convert 32 remaining widget.Select to ColoredSelect --- ### 🤖 opencode -**Status**: Has uncommitted job editing feature +**Status**: 🎯 PRIORITY HANDOFF - Fix compilation errors + widget deduplication -**Uncommitted Work** (Discovered by Claude): -- `internal/queue/edit.go` (NEW - 363 lines) - Job editing logic -- `internal/ui/command_editor.go` (NEW - 352 lines) - Fyne UI dialog -- `internal/queue/execute_edit_job.go.wip` (NEW - 114 lines) - Moved out of build (has import errors) -- `internal/queue/queue.go` (MODIFIED) - Refactored code to edit.go +**🔥 IMMEDIATE TASKS** (from Claude): +1. **Fix 3 Compilation Errors** in main.go: + - Line 500: `canvas.NewImageFromBytes` undefined + - Context: QR code generation in `generatePixelatedQRCode()` + - May need to use `canvas.NewImageFromResource()` or similar + - Lines 6995-7003: `outputExtLabel`, `outputExtBG`, `updateOutputHint` undefined + - Context: Convert UI output file extension handling + - Variables were likely removed/renamed - need to investigate and restore proper implementation -**Feature**: Job editing system with FFmpeg command management -- Edit FFmpeg commands in queued jobs -- Validate syntax and structure -- Track edit history with timestamps -- Apply/reset/revert functionality +2. **Widget Deduplication** (4 remaining pairs): + - resolutionSelectSimple & resolutionSelect (lines ~8009, 8347) + - targetAspectSelect & targetAspectSelectSimple (lines ~7397, 8016) + - encoderPresetSelect & simplePresetSelect (lines ~7531, 7543) + - bitratePresetSelect & simpleBitrateSelect (lines ~7969, 7982) + - **Pattern**: Follow quality widget example at main.go:7075-7128 -**Completeness**: ⚠️ INCOMPLETE -- ✅ Core logic complete, code compiles -- ❌ No integration in main.go (EditJobManager never instantiated) -- ❌ No UI hookups ("Edit Command" button missing from queue view) -- ❌ No end-to-end workflow testing -- ❌ Potential memory safety issue (queue.Get() shallow copy) +3. **ColoredSelect Expansion** (32 remaining widgets): + - Resolution, aspect, preset, bitrate, frame rate, etc. + - Use appropriate color maps (BuildGenericColorMap, BuildQualityColorMap, etc.) -**Last Known Work**: -- Player backend improvements +**Uncommitted Work** (Defer to later): +- `internal/queue/edit.go` - Job editing logic (keep for future dev24+) +- `internal/ui/command_editor.go` - Fyne UI dialog - Enhancement module framework -- Command execution refactoring -**Shared Responsibilities with Claude**: -- Convert module UI/UX improvements -- Queue system enhancements -- Module integration testing +**Coordination**: +- Jake will be using Codex for UI work this week +- Focus on build stability and widget conversions first --- ## 🤝 Coordination Status -**Opencode's Recommendation**: ✅ ACCEPTED - Option A +**Current Handoff**: Claude → opencode -**Actions Taken by Claude**: -1. ✅ Removed partial job editing integration from queueview.go: - - Removed onEditJob parameter from buildJobItem signature - - Removed Edit button code for JobTypeEditJob - - Added missing "image" import -2. ✅ Removed job editing integration from main.go: - - Removed editJobManager field from appState struct - - Removed JobTypeEditJob case statement - - Removed executeEditJob function (150 lines) - - Removed editJobManager initialization -3. ✅ Preserved WIP files for dev23: - - internal/queue/edit.go (not committed, ready for dev23) - - internal/ui/command_editor.go (not committed, ready for dev23) - - internal/queue/execute_edit_job.go.wip (needs import fixes) -4. ✅ Build passing and ready for testing +**Claude's Handoff** (2026-01-04 10:00): +1. ✅ Quality widget deduplication complete (pattern established) +2. ✅ Enhancement module compilation fixed +3. ✅ Missing imports restored +4. ⚠️ 3 compilation errors remain - handed off to opencode +5. 📋 4 widget pairs still need deduplication +6. 📋 32 widgets need ColoredSelect conversion -**Next Steps**: -- Test dev22 features (GPU detection, AV1 presets, UI improvements) -- Push to remote: `git push origin master --tags` -- Begin dev23 planning with job editing integration as priority feature +**For opencode**: +- Priority 1: Fix 3 compilation errors (blocking build) +- Priority 2: Complete widget deduplication using established pattern +- Priority 3: ColoredSelect expansion for remaining 32 widgets + +**Coordination Notes**: +- User will be using Codex for UI work this week - coordinate visual changes +- Build must pass before UI work can continue --- diff --git a/assets/logo/LT_Logo-26.png b/assets/logo/LT_Logo-26.png new file mode 100644 index 0000000000000000000000000000000000000000..5181025e28aa0ef94bb036a75dc4fe5119b45f7e GIT binary patch literal 30740 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 literal 0 HcmV?d00001 diff --git a/assets/logo/VT_Prototype.svg b/assets/logo/VT_Prototype.svg deleted file mode 100644 index 20abcc7..0000000 --- a/assets/logo/VT_Prototype.svg +++ /dev/null @@ -1,639 +0,0 @@ - - - -< CONVERTVIDEOTOOLSCONVERTMERGETRIMFILTERSUPSCALEAUDIOTHUMBINSPECTQUEUE: 1/4Video Display and simple controlssimple/advancedoptions and settings Video metadata andtechnical informationReset | CONVERT diff --git a/go.mod b/go.mod index 8212aff..a28b179 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,8 @@ require ( fyne.io/systray v1.11.1-0.20250603113521-ca66a66d8b58 // indirect github.com/BurntSushi/toml v1.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/ebitengine/oto/v3 v3.4.0 // indirect + github.com/ebitengine/purego v0.9.0 // indirect github.com/fredbi/uri v1.1.1 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fyne-io/gl-js v0.2.0 // indirect @@ -37,7 +39,7 @@ require ( github.com/yuin/goldmark v1.7.8 // indirect golang.org/x/image v0.24.0 // indirect golang.org/x/net v0.35.0 // indirect - golang.org/x/sys v0.30.0 // indirect + golang.org/x/sys v0.36.0 // indirect golang.org/x/text v0.22.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 7345530..4056db9 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,14 @@ github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ebitengine/oto/v3 v3.4.0 h1:br0PgASsEWaoWn38b2Goe7m1GKFYfNgnsjSd5Gg+/bQ= +github.com/ebitengine/oto/v3 v3.4.0/go.mod h1:IOleLVD0m+CMak3mRVwsYY8vTctQgOM0iiL6S7Ar7eI= +github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k= +github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= +github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fredbi/uri v1.1.1 h1:xZHJC08GZNIUhbP5ImTHnt5Ya0T8FI2VAwI/37kh2Ko= github.com/fredbi/uri v1.1.1/go.mod h1:4+DZQ5zBjEwQCDmXW5JdIjz0PUA+yJbvtBv+u+adr5o= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= @@ -33,6 +39,8 @@ github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066 h1:qCuYC github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/hack-pad/go-indexeddb v0.3.2 h1:DTqeJJYc1usa45Q5r52t01KhvlSN02+Oq+tQbSBI91A= @@ -51,6 +59,8 @@ github.com/nicksnyder/go-i18n/v2 v2.5.1 h1:IxtPxYsR9Gp60cGXjfuR/llTqV8aYMsC472zD github.com/nicksnyder/go-i18n/v2 v2.5.1/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA= github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -65,6 +75,12 @@ github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqd github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/yeqown/go-qrcode/v2 v2.2.5 h1:HCOe2bSjkhZyYoyyNaXNzh4DJZll6inVJQQw+8228Zk= +github.com/yeqown/go-qrcode/v2 v2.2.5/go.mod h1:uHpt9CM0V1HeXLz+Wg5MN50/sI/fQhfkZlOM+cOTHxw= +github.com/yeqown/go-qrcode/writer/standard v1.3.0 h1:chdyhEfRtUPgQtuPeaWVGQ/TQx4rE1PqeoW3U+53t34= +github.com/yeqown/go-qrcode/writer/standard v1.3.0/go.mod h1:O4MbzsotGCvy8upYPCR91j81dr5XLT7heuljcNXW+oQ= +github.com/yeqown/reedsolomon v1.0.0 h1:x1h/Ej/uJnNu8jaX7GLHBWmZKCAWjEJTetkqaabr4B0= +github.com/yeqown/reedsolomon v1.0.0/go.mod h1:P76zpcn2TCuL0ul1Fso373qHRc69LKwAw/Iy6g1WiiM= github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ= @@ -73,6 +89,8 @@ golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/enhancement/enhancement_module.go b/internal/enhancement/enhancement_module.go index 938ab04..1bb6396 100644 --- a/internal/enhancement/enhancement_module.go +++ b/internal/enhancement/enhancement_module.go @@ -5,9 +5,6 @@ import ( "fmt" "image" "image/color" - "image/draw" - "math" - "sort" "strings" "time" @@ -25,6 +22,18 @@ type AIModel interface { Close() error } +// SkinToneAnalysis represents detailed skin tone analysis for enhancement +type SkinToneAnalysis struct { + DetectedSkinTones []string // List of detected skin tones + SkinSaturation float64 // 0.0-1.0 + SkinBrightness float64 // 0.0-1.0 + SkinWarmth float64 // -1.0 to 1.0 (negative=cool, positive=warm) + SkinContrast float64 // 0.0-2.0 (1.0=normal) + DetectedHemoglobin []string // Detected hemoglobin levels/characteristics + IsAdultContent bool // Whether adult content was detected + RecommendedProfile string // Recommended enhancement profile +} + // ContentAnalysis represents video content analysis results type ContentAnalysis struct { Type string // "general", "anime", "film", "interlaced", "adult" @@ -144,17 +153,10 @@ func (m *EnhancementModule) AnalyzeContent(path string) (*ContentAnalysis, error // Advanced skin analysis for Phase 2.5 advancedSkinAnalysis := m.analyzeSkinTonesAdvanced(output) - + // Update content analysis with advanced skin tone information - contentAnalysis.SkinTones = advancedSkinAnalysis.DetectedSkinTones - contentAnalysis.SkinSaturation = advancedSkinAnalysis.SkinSaturation - contentAnalysis.SkinBrightness = advancedSkinAnalysis.SkinBrightness - contentAnalysis.SkinWarmth = advancedSkinAnalysis.SkinWarmth - contentAnalysis.SkinContrast = advancedSkinAnalysis.SkinContrast - contentAnalysis.DetectedHemoglobin = advancedSkinAnalysis.DetectedHemoglobin - contentAnalysis.IsAdultContent = advancedSkinAnalysis.IsAdultContent - contentAnalysis.RecommendedProfile = advancedSkinAnalysis.RecommendedProfile - + contentAnalysis.SkinTones = advancedSkinAnalysis + logging.Debug(logging.CatEnhance, "Advanced skin analysis applied: %+v", advancedSkinAnalysis) return contentAnalysis, nil } @@ -190,18 +192,12 @@ func (m *EnhancementModule) analyzeSkinTonesAdvanced(ffprobeOutput []byte) *Skin RecommendedProfile: "balanced", // Default enhancement profile } - // Advanced frame-by-frame skin tone detection - frameCount := 0 - skinToneHistogram := make(map[string]int) // [skin_tone]count - totalSaturation := 0.0 - totalBrightness := 0.0 - totalWarmth := 0.0 - totalCoolness := 0.0 - - // For now, simulate frame-by-frame skin analysis - // In production, this would process actual video frames - // Here we detect dominant skin tones and distribution across frames - + // TODO: Advanced frame-by-frame skin tone detection would use: + // - frameCount for tracking processed frames + // - skinToneHistogram for tone distribution + // - totalSaturation, totalBrightness, totalWarmth, totalCoolness for averages + // This will be implemented when video frame processing is added + return analysis } diff --git a/internal/enhancement/onnx_model.go b/internal/enhancement/onnx_model.go index 32ce6ed..0e2bd1f 100644 --- a/internal/enhancement/onnx_model.go +++ b/internal/enhancement/onnx_model.go @@ -106,7 +106,6 @@ func (m *ONNXModel) enhancePixel(c color.RGBA) color.RGBA { // Simple enhancement: increase contrast and sharpness g := float64(c.G) b := float64(c.B) - a := float64(c.A) // Boost contrast (1.1x) g = min(255, g*1.1) diff --git a/main.go b/main.go index 44fb34e..8837dd0 100644 --- a/main.go +++ b/main.go @@ -1,18 +1,25 @@ package main import ( + "bufio" "bytes" "context" + "encoding/json" + "errors" "flag" "fmt" "image/color" + "io" "log" + "math" "net/url" "os" "os/exec" "path/filepath" "runtime" "slices" + "sort" + "strconv" "strings" "sync" "sync/atomic" diff --git a/qr-demo/go.mod b/qr-demo/go.mod new file mode 100644 index 0000000..3319012 --- /dev/null +++ b/qr-demo/go.mod @@ -0,0 +1,8 @@ +module qr-demo + +go 1.25.5 + +require ( + fyne.io/fyne/v2 v2.7.1 // indirect + github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect +) diff --git a/qr-demo/go.sum b/qr-demo/go.sum new file mode 100644 index 0000000..64daadc --- /dev/null +++ b/qr-demo/go.sum @@ -0,0 +1,4 @@ +fyne.io/fyne/v2 v2.7.1 h1:ja7rNHWWEooha4XBIZNnPP8tVFwmTfwMJdpZmLxm2Zc= +fyne.io/fyne/v2 v2.7.1/go.mod h1:xClVlrhxl7D+LT+BWYmcrW4Nf+dJTvkhnPgji7spAwE= +github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= +github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= diff --git a/qr-demo/qr_about_demo.go b/qr-demo/qr_about_demo.go new file mode 100644 index 0000000..8c5fd66 --- /dev/null +++ b/qr-demo/qr_about_demo.go @@ -0,0 +1,99 @@ +package main + +import ( + "bytes" + "fmt" + "log" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/app" + "fyne.io/fyne/v2/canvas" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/layout" + "fyne.io/fyne/v2/widget" + + "github.com/skip2/go-qrcode" +) + +func generatePixelatedQRCode() (fyne.CanvasObject, error) { + docURL := "https://docs.leaktechnologies.dev/VideoTools" + + // Generate QR code with large pixels for blocky look (160x160 with 8x8 pixel blocks) + qrBytes, err := qrcode.Encode(docURL, qrcode.Medium, 160) + if err != nil { + return nil, err + } + + // Convert to Fyne image with pixelated look + img := canvas.NewImageFromBytes(qrBytes) + img.FillMode = canvas.ImageFillOriginal // Keep pixelated look + img.SetMinSize(fyne.NewSize(160, 160)) + + return img, nil +} + +func main() { + myApp := app.New() + myWindow := myApp.NewWindow("QR Code Test - About Dialog Demo") + + // Test QR generation + qrCode, err := generatePixelatedQRCode() + if err != nil { + log.Printf("Failed to generate QR code: %v", err) + fallback := widget.NewLabel("QR generation failed - using fallback") + myWindow.SetContent(container.NewVBox(fallback)) + } else { + // Recreate about dialog layout with QR code + title := canvas.NewText("About & Support", color.Color{} /*textColor*/) + title.TextSize = 20 + + versionText := widget.NewLabel("VideoTools QR Code Demo") + devText := widget.NewLabel("Developer: Leak Technologies") + + // QR code with label + qrLabel := widget.NewLabel("Scan for docs") + qrLabel.Alignment = fyne.TextAlignCenter + + // Logs button + logsLink := widget.NewButton("Logs Folder", func() { + fmt.Println("Logs folder clicked") + }) + logsLink.Importance = widget.LowImportance + + feedbackLabel := widget.NewLabel("Feedback: use Logs button on main menu to view logs; send issues with attached logs.") + feedbackLabel.Wrapping = fyne.TextWrapWord + + mainContent := container.NewVBox( + versionText, + devText, + widget.NewLabel(""), + widget.NewLabel("Support Development"), + widget.NewLabel("QR code demo for docs"), + feedbackLabel, + ) + + logoColumn := container.NewVBox() + logoColumn.Add(qrCode) + logoColumn.Add(qrLabel) + logoColumn.Add(layout.NewSpacer()) + logoColumn.Add(logsLink) + + body := container.NewBorder( + container.NewHBox(title), + nil, + nil, + logoColumn, + mainContent, + ) + body = container.NewPadded(body) + sizeShim := canvas.NewRectangle(color.Transparent{}) + sizeShim.SetMinSize(fyne.NewSize(560, 280)) + + content := container.NewMax(sizeShim, body) + myWindow.SetContent(content) + } + + myWindow.Resize(fyne.NewSize(600, 400)) + myWindow.CenterOnScreen() + myWindow.ShowAndRun() +}