Files
umbrix-libcore/extension/extension.go
2024-09-30 21:27:18 +02:00

140 lines
3.0 KiB
Go

package extension
import (
"reflect"
"github.com/hiddify/hiddify-core/config"
"github.com/hiddify/hiddify-core/extension/ui"
pb "github.com/hiddify/hiddify-core/hiddifyrpc"
"github.com/hiddify/hiddify-core/v2/db"
"github.com/jellydator/validation"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
)
type Extension interface {
GetUI() ui.Form
SubmitData(button string, data map[string]string) error
Cancel() error
Stop() error
UpdateUI(form ui.Form) error
BeforeAppConnect(hiddifySettings *config.HiddifyOptions, singconfig *option.Options) error
StoreData()
init(id string)
getQueue() chan *pb.ExtensionResponse
getId() string
}
type Base[T any] struct {
id string
// responseStream grpc.ServerStreamingServer[pb.ExtensionResponse]
queue chan *pb.ExtensionResponse
Data T
}
// func (b *Base) mustEmbdedBaseExtension() {
// }
func (b *Base[T]) BeforeAppConnect(hiddifySettings *config.HiddifyOptions, singconfig *option.Options) error {
return nil
}
func (b *Base[T]) StoreData() {
table := db.GetTable[extensionData]()
table.Update(func(s extensionData) extensionData {
s.Data = b.Data
return s
}, func(data extensionData) bool {
return data.Id == b.getId()
})
}
func (b *Base[T]) init(id string) {
b.id = id
b.queue = make(chan *pb.ExtensionResponse, 1)
table := db.GetTable[extensionData]()
extdata, err := table.First(func(data extensionData) bool { return data.Id == b.id })
if err != nil {
log.Warn("error: ", err)
return
}
if extdata == nil {
log.Warn("extension data not found ", id)
return
}
if extdata.Data != nil {
if data, ok := extdata.Data.(*T); ok {
b.Data = *data
} else {
var t T
name := reflect.TypeOf(t).Name()
log.Warn("current extension data of ,", id, " is not of type ", name)
}
}
}
func (b *Base[T]) getQueue() chan *pb.ExtensionResponse {
return b.queue
}
func (b *Base[T]) getId() string {
return b.id
}
func (e *Base[T]) ShowMessage(title string, msg string) error {
return e.ShowDialog(ui.Form{
Title: title,
Description: msg,
Fields: [][]ui.FormField{
{{
Type: ui.FieldButton,
Key: ui.Button_Ok,
Label: "Ok",
}},
},
// Buttons: []string{ui.Button_Ok},
})
}
func (p *Base[T]) UpdateUI(form ui.Form) error {
p.queue <- &pb.ExtensionResponse{
ExtensionId: p.id,
Type: pb.ExtensionResponseType_UPDATE_UI,
JsonUi: form.ToJSON(),
}
return nil
}
func (p *Base[T]) ShowDialog(form ui.Form) error {
p.queue <- &pb.ExtensionResponse{
ExtensionId: p.id,
Type: pb.ExtensionResponseType_SHOW_DIALOG,
JsonUi: form.ToJSON(),
}
// log.Printf("Updated UI for extension %s: %s", err, p.id)
return nil
}
func (base *Base[T]) ValName(fieldPtr interface{}) string {
val, err := validation.ErrorFieldName(&base.Data, fieldPtr)
if err != nil {
log.Warn(err)
return ""
}
if val == "" {
log.Warn("Field not found")
return ""
}
return val
}
type ExtensionFactory struct {
Id string
Title string
Description string
Builder func() Extension
}