bakes82 167 Posted September 17, 2023 Author Posted September 17, 2023 @softworkzI took my fileds put them in the SampleUI project, built it, same error, reverted back the project, rebuilt it, and now sample is broken too I press save I see the data in the json file, press "refresh" still shows previously entered data.
softworkz 5066 Posted September 17, 2023 Posted September 17, 2023 (edited) 1 hour ago, bakes82 said: @softworkzYes Generally, the BasePluginSimpleUi is meant for the most simple cases of configurations, where you only have a few properties to display and to save. The advantage of this way is that it's incredibly easy to do and it requires a minimal amount of code only, due to the fact that the UI model is identical to the storage model (for saving the configuration). As soon as the requirements for the config UI get a little more complex, though, this can quickly turn into a drawback as you are unable to modify the UI independently from the storage format. We have already created around 70 different plugin pages for various plugins and future features, so it's not like that all of this is untested and experimental, but none of those cases uses the BasePluginSimpleUi, so this bug remained unnoticed. I was able to identify and fix it now for the next beta. If you need a (dirty) workaround meanwhile, you can add this to your plugin class: protected override bool OnOptionsSaving(TOptionType options) { var currentOptions = this.GetOptions(); currentOptions.ApiKey = options.ApiKey; currentOptions.Channel1 = options.Channel1; return true; } Edited September 17, 2023 by softworkz
bakes82 167 Posted September 17, 2023 Author Posted September 17, 2023 5 minutes ago, softworkz said: Generally, the BasePluginSimpleUi is meant for the most simple cases of configurations, where you only have a few properties to display and to save. The advantage of this way is that it's incredibly easy to do and it requires a minimal amount of code only, due to the fact that the UI model is identical to the storage model (for saving the configuration). As soon as the requirements for the config UI get a little more complex, though, this can quickly turn into a drawback as you are unable to modify the UI independently from the storage format. We have already created around 70 different plugin pages for various plugins and future features, so it's not like that all of this is untested and experimental, but none of those cases uses the BasePluginSimpleUi, so this bug remained unnoticed. I was able to identify and fix it now for the next beta. If you need to (dirty) workaround meanwhile, you can add this to your plugin class: protected override bool OnOptionsSaving(TOptionType options) { var currentOptions = this.GetOptions(); currentOptions.ApiKey = options.ApiKey; currentOptions.Channel1 = options.Channel1; return true; } @softworkzCan confirm, this "hack" works. You got eta on next build? I didnt think my options were too complex
softworkz 5066 Posted September 17, 2023 Posted September 17, 2023 (edited) 7 minutes ago, bakes82 said: I didnt think my options were too complex No, for the current, it's just fine! But you should think about where it might go over time once your plugin evolves. Sometimes you know right away "that's it" and that's all what will ever be needed, elsewise it could grow and config might get more complicated, but that's something for you to decide.. 7 minutes ago, bakes82 said: You got eta on next build? If there's one Emby thing that I can never predict, then it's the release date of the next beta... LOL Edited September 17, 2023 by softworkz
bakes82 167 Posted September 20, 2023 Author Posted September 20, 2023 (edited) On 9/16/2023 at 8:22 PM, softworkz said: I just noticed that there's a bug at the client side for which it doesn't dynamically change the item count. But here's an example for how it's supposed to work. Based in the example project,.... Change ChildOptionExample to this: namespace EmbyPluginUiDemo.Model { using System.Collections; using System.Collections.Generic; using System.ComponentModel; using Emby.Web.GenericEdit; using MediaBrowser.Model.Attributes; using IEditableObject = MediaBrowser.Model.GenericEdit.IEditableObject; public class ChildOptionExample : EditableOptionsBase { public override string EditorTitle => ""; [DisplayName("")] [EditFilePicker] [AutoPostBack("PostBack", nameof(File))] public string File { get; set; } } public class ChildOptionExampleCollection : List<ChildOptionExample>, IEditableObjectCollection, IEnumerable<ChildOptionExample>, IEnumerable { public ChildOptionExampleCollection() { } public ChildOptionExampleCollection(IEnumerable<ChildOptionExample> collection) : base(collection) { } public ChildOptionExampleCollection(int capacity) : base(capacity) { } IEnumerator<IEditableObject> IEnumerable<IEditableObject>.GetEnumerator() => (IEnumerator<IEditableObject>) this.GetEnumerator(); IEnumerator<ChildOptionExample> IEnumerable<ChildOptionExample>.GetEnumerator() => (IEnumerator<ChildOptionExample>) this.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => (IEnumerator) this.GetEnumerator(); } } Change NestingPageView to this: namespace EmbyPluginUiDemo.UI.Nesting { using System.Threading.Tasks; using Emby.Media.Common.Extensions; using EmbyPluginUiDemo.Model; using EmbyPluginUiDemo.UIBaseClasses.Views; using MediaBrowser.Model.Plugins; using MediaBrowser.Model.Plugins.UI.Views; internal class NestingPageView : PluginPageView { public NestingPageView(PluginInfo pluginInfo) : base(pluginInfo.Id) { this.ContentData = new NestingUI(); } public NestingUI NestingUI => this.ContentData as NestingUI; public override bool IsCommandAllowed(string commandKey) { if (commandKey == "PostBack") { return true; } return base.IsCommandAllowed(commandKey); } public override Task<IPluginUIView> RunCommand(string itemId, string commandId, string data) { if (commandId == "PostBack") { this.NestingUI.Collection.RemoveAll(e => ((ChildOptionExample)e).File.IsNullOrEmpty()); this.NestingUI.Collection.Add(new ChildOptionExample()); return Task.FromResult((IPluginUIView)this); } return base.RunCommand(itemId, commandId, data); } } } And in NestingUI, change the Collection property to this: [DisplayName("Dynamic Collection of Child Options")] public ChildOptionExampleCollection Collection { get; set; } = new ChildOptionExampleCollection { new ChildOptionExample(), }; I'll try to get the client issue fixed asap. Am I correct in understanding that this wont work for me untill the new sdk? I was soooooooo excided that I finally got to this and its like nah I also saw this in my json, is this correct? "PathsToIgnore": [ { "FolderPath": "/media/Audio" }, { } ] Edited September 20, 2023 by bakes82
softworkz 5066 Posted September 20, 2023 Posted September 20, 2023 6 minutes ago, bakes82 said: Am I correct in understanding that this wont work for me untill the new sdk? I was soooooooo excided that I finally got to this and its like nah This doesn't require an SDK update as it's client-side code. The fix will be in the next beta server. And also on http://app.emby.media (not yet, but probably very soon).
bakes82 167 Posted September 20, 2023 Author Posted September 20, 2023 2 minutes ago, softworkz said: This doesn't require an SDK update as it's client-side code. The fix will be in the next beta server. And also on http://app.emby.media (not yet, but probably very soon). Hmm, it doesnt seem to be auto refreshing the UI, if I press "reload" I see the new entry though and I see it hitting the post back in the logs.
softworkz 5066 Posted September 20, 2023 Posted September 20, 2023 12 minutes ago, bakes82 said: And also on http://app.emby.media (not yet, but probably very soon).
bakes82 167 Posted September 20, 2023 Author Posted September 20, 2023 @softworkzAm I missing something lol? Im testing this on my local webUi.
softworkz 5066 Posted September 20, 2023 Posted September 20, 2023 You were asking when this bug will be fixed. And I said 30 minutes ago, softworkz said: This doesn't require an SDK update as it's client-side code. The fix will be in the next beta server. And also on http://app.emby.media (not yet, but probably very soon). So, why are you wondering that is doesn't work?
bakes82 167 Posted September 20, 2023 Author Posted September 20, 2023 (edited) 4 minutes ago, softworkz said: You were asking when this bug will be fixed. And I said So, why are you wondering that is doesn't work? When you say its not a SDK fix and its a "client fix" I assumed you meant the code you provide was the "client ui" rendering code, so the answer is, yes you guys still need to publish code some place for this to work I understand now. I can get by with add item, save, refresh ui, add item, save. Edited September 20, 2023 by bakes82
softworkz 5066 Posted September 20, 2023 Posted September 20, 2023 42 minutes ago, bakes82 said: so the answer is, yes you guys still need to publish code some place for this to work I understand now. Yes, it's the htmljs client rendering code of the apps (and the web ui served by the server.
bakes82 167 Posted September 20, 2023 Author Posted September 20, 2023 @softworkzDoes the new ui stuff have "buttons" so I can trigger some things manually or just run some server-side code?
bakes82 167 Posted September 20, 2023 Author Posted September 20, 2023 1 hour ago, softworkz said: Yes, of course: I didnt see any buttons that have postbacks/links, so I tried this but it doesnt seem to work. [AutoPostBack("SplitMovies", nameof(SplitMoviesButton))] public ButtonItem SplitMoviesButton { get; set; } = new ButtonItem { Caption = "Split Movies", Icon = IconNames.splitscreen };
softworkz 5066 Posted September 20, 2023 Posted September 20, 2023 Oh, I see - there's no good example yet for buttons. Here's the code for the two buttons on the 2nd screenshot. The UI class: And the view class: Buttons are always causing a postback.What's important is to specify a commandId for the Data1 property. Then you just need to handle RunCommand in the view class.
bakes82 167 Posted September 20, 2023 Author Posted September 20, 2023 10 hours ago, softworkz said: Buttons are always causing a postback.What's important is to specify a commandId for the Data1 property. Then you just need to handle RunCommand in the view class. Maybe you could just make another setter called "CommandId" and have it set Data1 to make it a little more clear
bakes82 167 Posted September 20, 2023 Author Posted September 20, 2023 (edited) It tells me the command isnt found. NM: it wasnt returning and it was falling thru to the base. @softworkz public ButtonItem SplitMoviesButton { get; set; } = new ButtonItem { Data1 ="SplitMovies", Data2 = null, Caption = "Split Movies", Icon = IconNames.splitscreen }; public override bool IsCommandAllowed(string commandKey) { if (commandKey is "PostBack" or "SplitMovies" or "SplitTv" ) return true; return base.IsCommandAllowed(commandKey); } public override Task<IPluginUIView> RunCommand(string itemId, string commandId, string data) { if (commandId == "PostBack") { _logger.Info("in postback"); PluginUi.PathsToIgnore.RemoveAll(e => e.FolderPath.IsNullOrEmpty()); PluginUi.PathsToIgnore.Add(new FolderPathEO()); return Task.FromResult((IPluginUIView)this); } if (commandId == "SplitMovies") { _logger.Info("in split movies"); var manager = new MergeVersionManager(_libraryManager, PluginUi, _fileSystem, _logger); manager.SplitMovies(new Progress<double>()); } if(commandId == "SplitTv") { _logger.Info("in split tv"); var manager = new MergeVersionManager(_libraryManager, PluginUi, _fileSystem, _logger); manager.SplitEpisodes(new Progress<double>()); } return base.RunCommand(itemId, commandId, data); } Edited September 20, 2023 by bakes82
softworkz 5066 Posted September 20, 2023 Posted September 20, 2023 3 hours ago, bakes82 said: Maybe you could just make another setter called "CommandId" and have it set Data1 to make it a little more clear That's a good idea. Definitely makes sense!
softworkz 5066 Posted September 20, 2023 Posted September 20, 2023 3 hours ago, bakes82 said: It tells me the command isnt found. You need to return the view which should be shown next. If the view should remain the same, you need to do like in the PostBack case: return Task.FromResult((IPluginUIView)this);
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now