diff --git a/pkg/download/extension.go b/pkg/download/extension.go index f996aff18..57637dad9 100644 --- a/pkg/download/extension.go +++ b/pkg/download/extension.go @@ -422,8 +422,50 @@ func (e *Extension) update(newExt *Extension) error { e.Homepage = newExt.Homepage e.Repository = newExt.Repository e.Scripts = newExt.Scripts - // don't override settings - //e.Settings = newExt.Settings + // merge settings + // if new setting not exist in old settings, append it + for _, newSetting := range newExt.Settings { + var exist bool + for _, setting := range e.Settings { + if setting.Name == newSetting.Name { + exist = true + break + } + } + if !exist { + e.Settings = append(e.Settings, newSetting) + } + } + // if old setting not exist in new settings, remove it + for i := 0; i < len(e.Settings); i++ { + var exist bool + for _, setting := range newExt.Settings { + if setting.Name == e.Settings[i].Name { + exist = true + break + } + } + if !exist { + e.Settings = append(e.Settings[:i], e.Settings[i+1:]...) + i-- + } + } + // if new setting exist in old settings, update it + for _, newSetting := range newExt.Settings { + for _, setting := range e.Settings { + if setting.Name == newSetting.Name { + setting.Title = newSetting.Title + setting.Description = newSetting.Description + setting.Options = newSetting.Options + // if type changed, reset value + if setting.Type != newSetting.Type { + setting.Type = newSetting.Type + setting.Value = newSetting.Value + } + break + } + } + } e.UpdatedAt = time.Now() return nil } diff --git a/pkg/download/extension_test.go b/pkg/download/extension_test.go index 6211e6477..fa5e7c044 100644 --- a/pkg/download/extension_test.go +++ b/pkg/download/extension_test.go @@ -95,6 +95,15 @@ func TestDownloader_InstallExtensionByGitFull(t *testing.T) { } func TestDownloader_UpgradeExtension(t *testing.T) { + getSetting := func(settings []*Setting, name string) *Setting { + for _, setting := range settings { + if setting.Name == name { + return setting + } + } + return nil + } + setupDownloader(func(downloader *Downloader) { installedExt, err := downloader.InstallExtensionByFolder("./testdata/extensions/update", false) if err != nil { @@ -122,14 +131,35 @@ func TestDownloader_UpgradeExtension(t *testing.T) { t.Fatal("extension update fail") } + // check setting update + s1 := getSetting(upgradeExt.Settings, "s1") + if s1.Title == "S1 old" { + t.Fatal("setting update fail") + } + // check setting type update + s2 := getSetting(upgradeExt.Settings, "s2") + if s2.Type == "number" { + t.Fatal("setting type update fail") + } + // check setting remove + d1 := getSetting(upgradeExt.Settings, "d1") + if d1 != nil { + t.Fatal("setting remove fail") + } + // check setting add + s3 := getSetting(upgradeExt.Settings, "s3") + if s3 == nil { + t.Fatal("setting add fail") + } + rr, err := downloader.Resolve(&base.Request{ - URL: "https://github.com/GopeedLab/gopeed/releases", + URL: "https://test.com", }) if err != nil { t.Fatal(err) } - if len(rr.Res.Files) == 1 { - t.Fatal("resolve error") + if rr.Res.Name != "test" { + t.Fatal("script update fail") } }) } diff --git a/pkg/download/testdata/extensions/update/manifest.json b/pkg/download/testdata/extensions/update/manifest.json index 9db763f85..f3cb1c99a 100644 --- a/pkg/download/testdata/extensions/update/manifest.json +++ b/pkg/download/testdata/extensions/update/manifest.json @@ -1,13 +1,13 @@ { - "name": "github-release", + "name": "extension-test", "author": "gopeed", - "title": "Github Release", - "description": "Download github release assets", + "title": "Gopeed Extension Test", + "description": "Test extension settings and upgrade", "version": "0.0.1", "homepage": "https://gopeed.com", "repository": { "url": "https://github.com/GopeedLab/gopeed-extension-samples", - "directory": "github-release-sample" + "directory": "extension-test" }, "scripts": [ { @@ -19,5 +19,29 @@ }, "entry": "index.js" } + ], + "settings": [ + { + "name": "s1", + "title": "S1 old", + "description": "Test setting update", + "type": "string", + "required": true + }, + { + "name": "s2", + "title": "s2 number old", + "description": "Test setting type update", + "type": "number", + "required": true, + "value": 1 + }, + { + "name": "d1", + "title": "Delete test", + "description": "Test setting delete", + "type": "string", + "required": true + } ] } \ No newline at end of file diff --git a/ui/flutter/lib/app/modules/extension/views/extension_view.dart b/ui/flutter/lib/app/modules/extension/views/extension_view.dart index f5d07e7a9..587d6d71d 100644 --- a/ui/flutter/lib/app/modules/extension/views/extension_view.dart +++ b/ui/flutter/lib/app/modules/extension/views/extension_view.dart @@ -256,9 +256,32 @@ class ExtensionView extends GetView { Expanded( child: SingleChildScrollView( child: Column( - children: extension.settings! - .map((e) => _buildSettingItem(e)) - .toList()), + children: extension.settings!.map((e) { + final settingItem = _buildSettingItem(e); + + return Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + SizedBox( + width: 20, + child: e.description.isEmpty + ? null + : Tooltip( + message: e.description, + child: const CircleAvatar( + radius: 10, + backgroundColor: + Colors.grey, + child: Icon( + Icons.question_mark, + size: 10, + )), + )) + .paddingOnly(right: 10), + Expanded(child: settingItem), + ], + ); + }).toList()), ), ), ]), @@ -324,8 +347,7 @@ class ExtensionView extends GetView { FormFieldValidator? validator, TextInputType? keyBoardType) { return FormBuilderTextField( name: setting.name, - decoration: InputDecoration( - labelText: setting.title, hintText: setting.description), + decoration: InputDecoration(labelText: setting.title), initialValue: setting.value?.toString(), inputFormatters: inputFormatter != null ? [inputFormatter] : null, keyboardType: keyBoardType, @@ -340,7 +362,8 @@ class ExtensionView extends GetView { return FormBuilderDropdown( name: setting.name, decoration: InputDecoration( - labelText: setting.title, hintText: setting.description), + labelText: setting.title, + ), initialValue: setting.value?.toString(), validator: FormBuilderValidators.compose([ requiredValidator,