fckeuspy-go/fyne_ui.go
2025-09-22 18:52:15 +02:00

154 lines
3.5 KiB
Go

package main
import (
"errors"
encrypt "fckeuspy-go/lib"
"path/filepath"
"strings"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/widget"
)
func NewUI() (stprageDir string, window fyne.Window) {
// App + storage dir
a := app.New()
w := a.NewWindow("Encryptor (Fyne)")
prefs := a.Preferences()
width := prefs.IntWithFallback("winW", 1100)
height := prefs.IntWithFallback("winH", 720)
w.Resize(fyne.NewSize(float32(width), float32(height)))
w.SetOnClosed(func() {
sz := w.Canvas().Size()
prefs.SetInt("winW", int(sz.Width))
prefs.SetInt("winH", int(sz.Height))
})
// docasny bypass
/*
base, err := os.UserConfigDir()
if err != nil {
base, _ = os.UserHomeDir()
}
*/
base := "./"
//return filepath.Join(base, "fckeuspy-go"), w
return filepath.Join(base, ""), w
}
// ShowPasswordVaultDialog zobrazí dialog pro vytvoření nebo otevření trezoru.
// Zatím pouze skeleton: vrací heslo přes callback, reálné volání CreateEncryptedStore/OpenEncryptedStore mimo.
func ShowPasswordVaultDialog(w fyne.Window, onResult func(create bool, password string)) {
pwEntry := widget.NewPasswordEntry()
pwEntry.SetPlaceHolder("Heslo…")
pw2Entry := widget.NewPasswordEntry()
pw2Entry.SetPlaceHolder("Znovu heslo…")
strengthBar := widget.NewProgressBar()
strengthBar.Min = 0
strengthBar.Max = 100
strengthLabel := widget.NewLabel("")
updateStrength := func(pw string) {
score, desc := simpleScore(pw)
strengthBar.SetValue(float64(score))
strengthLabel.SetText(desc)
}
pwEntry.OnChanged = updateStrength
genBtn := widget.NewButton("Generovat", func() {
if v, err := encrypt.GenerateRandomPassword(20); err == nil {
pwEntry.SetText(v)
pw2Entry.SetText(v)
updateStrength(v)
}
})
modeCreate := true
var toggle *widget.Button
toggle = widget.NewButton("Režim: Vytvořit (klikni pro Otevřít)", func() {
modeCreate = !modeCreate
if modeCreate {
toggle.SetText("Režim: Vytvořit (klikni pro Otevřít)")
pw2Entry.Enable()
} else {
toggle.SetText("Režim: Otevřít (klikni pro Vytvořit)")
pw2Entry.Disable()
}
})
form := &widget.Form{Items: []*widget.FormItem{
{Text: "Heslo", Widget: pwEntry},
{Text: "Potvrzení", Widget: pw2Entry},
}}
meter := container.NewVBox(strengthBar, strengthLabel)
topRow := container.NewBorder(nil, nil, nil, genBtn, meter)
content := container.NewVBox(toggle, topRow, form)
d := dialog.NewCustomConfirm("Trezor", "OK", "Zrušit", content, func(ok bool) {
if !ok {
onResult(false, "")
return
}
pw := pwEntry.Text
if modeCreate {
if pw != pw2Entry.Text {
dialog.NewError(errors.New("Hesla se neshodují"), w).Show()
return
}
if err := encrypt.ValidatePasswordForUI(pw); err != nil {
dialog.NewError(err, w).Show()
return
}
}
onResult(modeCreate, pw)
}, w)
d.Show()
}
// simpleScore: hrubá heuristika (0-100)
func simpleScore(pw string) (int, string) {
l := len(pw)
var u, lw, dg, sp int
specials := "!@#-_+="
for _, r := range pw {
switch {
case r >= 'A' && r <= 'Z':
u++
case r >= 'a' && r <= 'z':
lw++
case r >= '0' && r <= '9':
dg++
default:
if strings.ContainsRune(specials, r) {
sp++
}
}
}
cats := 0
if u > 0 {
cats++
}
if lw > 0 {
cats++
}
if dg > 0 {
cats++
}
if sp > 0 {
cats++
}
score := l*4 + cats*10
if score > 100 {
score = 100
}
desc := "Slabé"
switch {
case score >= 85:
desc = "Silné"
case score >= 60:
desc = "Dobré"
case score >= 30:
desc = "Střední"
}
return score, desc
}