Jump to content

Emby.web.genericedit nuget missing?


Recommended Posts

Posted

@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 :P  I press save I see the data in the json file, press "refresh" still shows previously entered data.

Posted (edited)
1 hour ago, bakes82 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 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 by softworkz
Posted
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 :P

Posted (edited)
7 minutes ago, bakes82 said:

I didnt think my options were too complex :P

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 by softworkz
Posted (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 :P

 

I also saw this in my json, is this correct?

 

"PathsToIgnore": [
        {
            "FolderPath": "/media/Audio"
        },
        {
            
        }
    ]

 

Edited by bakes82
Posted
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 :P

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).

Posted
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.

Posted

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?

Posted (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 by bakes82
Posted
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.

Posted

@softworkzDoes the new ui stuff have "buttons" so I can trigger some things manually or just run some server-side code?

Posted

Yes, of course:

 

image.png.1e21232ee39c3cd6b040406574e42701.png

 

 

 

image.png.525adcfc999d3d8cf57dbe4557a195e1.png

 

image.png.728abdc0d08ba51f7b7dbbc58c595409.png

Posted
1 hour ago, softworkz said:

Yes, of course:

 

image.png.1e21232ee39c3cd6b040406574e42701.png

 

 

 

image.png.525adcfc999d3d8cf57dbe4557a195e1.png

 

image.png.728abdc0d08ba51f7b7dbbc58c595409.png

 

 

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
                                                        };

 

Posted

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:

image.thumb.png.3831f4b13a584e9be0739bcc4bfcb552.png

 

And the view class:

image.png.2e1e034dcadb7ae765f04a9dd7519fdf.png

 

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.

Posted
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 ;)

Posted (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 by bakes82
Posted
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!

Posted
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);

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...