Luke 37066 Posted November 29, 2022 Share Posted November 29, 2022 You'll soon be able to create config screens that show up in user menus, rather than the server menu. The first recipient of this will be Trakt, so now each user can setup their Trakt integration without requiring the server admin to handle it for them: And a feature will be registered that allows admins to control access to the feature: I'm not sure who might have a use for this or not, but Trakt certainly does. @chef 8 Link to comment Share on other sites More sharing options...
chef 3745 Posted November 29, 2022 Share Posted November 29, 2022 I can absolutely think of ways this can be very useful. 1 Link to comment Share on other sites More sharing options...
Cheesegeezer 3086 Posted November 29, 2022 Share Posted November 29, 2022 That's awesome @Luke MediaInfo Toolbox can benefit from this also, allowing different users to display the info how they like it. Can you share the Interface class with use please. Great work as always fella!! 2 Link to comment Share on other sites More sharing options...
Luke 37066 Posted November 29, 2022 Author Share Posted November 29, 2022 2 minutes ago, Cheesegeezer said: That's awesome @Luke MediaInfo Toolbox can benefit from this also, allowing different users to display the info how they like it. Can you share the Interface class with use please. Great work as always fella!! Yup I'll have more info when the next beta drops. Trakt will be using it going forward. 1 Link to comment Share on other sites More sharing options...
chef 3745 Posted November 30, 2022 Share Posted November 30, 2022 This could be how @rbjtech gets his user based recommendations plugin rockin'. You could even allow users to build their own Top Picks. Endless possibilities. 1 1 Link to comment Share on other sites More sharing options...
rbjtech 4265 Posted November 30, 2022 Share Posted November 30, 2022 Sounds good - having a way to distribute administration/engagement to users is a big leap forward. I also came across the 'possibility' of adding context menu's options from a plugin as well. Looking forward to seeing what we can do ! 2 Link to comment Share on other sites More sharing options...
Junglejim 351 Posted November 30, 2022 Share Posted November 30, 2022 Yep this sounds great! My users don't have any admin access (that includes me , except for sub downloads). This sounds like a nice step forward to give users some control of some plugins etc. 1 Link to comment Share on other sites More sharing options...
Luke 37066 Posted November 30, 2022 Author Share Posted November 30, 2022 The notification plugins are going to get this as well, since those require linking with external (personal) accounts. Those will provide good sample code. @ackbarr @darkside40 Link to comment Share on other sites More sharing options...
Cheesegeezer 3086 Posted November 30, 2022 Share Posted November 30, 2022 Structurally how does this work. admin sets plugin accessibility User then sees the plugin UI and this is linked to a List<UserPluginPrefs> By name or pluginId. Or is it written to the plugin config.xml? if there are any examples to share after release it would be nice. Or comment the params for each interface method that woukd be lovely Link to comment Share on other sites More sharing options...
mickle026 400 Posted December 2, 2022 Share Posted December 2, 2022 I remember asking for this/how to do this a looooong time ago . Thrilled its finally coming Link to comment Share on other sites More sharing options...
Cheesegeezer 3086 Posted January 18, 2023 Share Posted January 18, 2023 @Luke @softworkz Where can i find this in the beta nugets. is there any sample code available to see the structure and requirements. Or can you point me to the correct interface to use please. Cheers Link to comment Share on other sites More sharing options...
BillOatman 500 Posted January 18, 2023 Share Posted January 18, 2023 On 11/29/2022 at 2:50 PM, chef said: I can absolutely think of ways this can be very useful. I bet you can 2 Link to comment Share on other sites More sharing options...
Cheesegeezer 3086 Posted January 18, 2023 Share Posted January 18, 2023 I’ve almost cracked it i think. My issues are getting current user, but ill muddle thru tomorrow. And hopefully have it finished Link to comment Share on other sites More sharing options...
Cheesegeezer 3086 Posted January 18, 2023 Share Posted January 18, 2023 (edited) Doh!! I just need to pass from the UI as a parameter to my Iservice class route!! What an idiot lol Edited January 18, 2023 by Cheesegeezer Link to comment Share on other sites More sharing options...
mickle026 400 Posted May 12, 2023 Share Posted May 12, 2023 Is there any examples of this yet? Link to comment Share on other sites More sharing options...
Cheesegeezer 3086 Posted May 12, 2023 Share Posted May 12, 2023 (edited) 1 hour ago, mickle026 said: Is there any examples of this yet? I kinda have it working a little in my YTPlugin. Need beta 28 or later i think. It's a lot more involved. Interface IConfigurationFactory (emby.media) Class ConfigurationStore (emby.media) using Emby.YouTube.Configuration.UserSettings; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Configuration; using System.Collections.Generic; namespace Emby.YouTube.Configuration { public class ConfigurationFactory : IUserConfigurationFactory { public static string ConfigKey = "YTChannel"; public IEnumerable<ConfigurationStore> GetConfigurations() { PluginConfigStore[] array = new PluginConfigStore[1]; PluginConfigStore YTConfigStore = new PluginConfigStore(); YTConfigStore.ConfigurationType = typeof(YTPluginUser); YTConfigStore.Key = ConfigKey; array[0] = YTConfigStore; return array; } } } using Emby.YouTube.Configuration.UserSettings; using MediaBrowser.Model.Plugins; using System; namespace Emby.YouTube.Configuration { public class YTPluginConfiguration : BasePluginConfiguration { public YTPluginUser[] YTPluginUsers { get; set; } = Array.Empty<YTPluginUser>(); } } using System; namespace Emby.YouTube.Configuration.UserSettings { public class YTPluginUser { public string YouTubeUsername { get; set; } public string YouTubePasswordHash { get; set; } public string YouTubeAuthTokenHash { get; set; } } } Then register this in the PluginConfigStore using System; using Emby.YouTube.Configuration.UserSettings; using MediaBrowser.Common.Configuration; namespace Emby.YouTube.Configuration; public class PluginConfigStore : ConfigurationStore, IValidatingConfiguration { public void Validate(object oldConfig, object newConfig) { if (oldConfig is YTPluginUser oldYTUser) { YTPluginUser newYTUser = (YTPluginUser)newConfig; if (!string.Equals(newYTUser.YouTubeUsername, oldYTUser.YouTubeUsername, StringComparison.OrdinalIgnoreCase) || string.IsNullOrEmpty(newYTUser.YouTubeUsername)) { newYTUser.YouTubeUsername = string.Empty; newYTUser.YouTubePasswordHash = string.Empty; } } } } The JS side //EMBY FUNCTIONS async function getUser() { return await ApiClient.getCurrentUserId(); } function fetchExistingConfiguration(userId) { return ApiClient.getTypedUserSettings(userId, 'YTChannel'); } function loadUserConfiguration(userId, view) { fetchExistingConfiguration(userId).then(function (config) { config.LocationsExcluded = config.LocationsExcluded || []; }); } inside the view function return function(view) { view.addEventListener('viewshow', async() => { loading.show(); mainTabsManager.setTabs(this, 0, getTabs); userId = await getUser(); loadUserConfiguration(userId, view); loading.hide(); //other functions to be carried out on load } } That's as far as i've got so far... i've not implemented the c# side for getting configs etc, but that should be pretty straight forward. Anyone let me know if there are ways i can improve this. Cheers Edited May 12, 2023 by Cheesegeezer 1 Link to comment Share on other sites More sharing options...
shure 24 Posted May 15, 2023 Share Posted May 15, 2023 On 5/12/2023 at 8:25 PM, Cheesegeezer said: I kinda have it working a little in my YTPlugin. Need beta 28 or later i think. It's a lot more involved. Interface IConfigurationFactory (emby.media) Class ConfigurationStore (emby.media) using Emby.YouTube.Configuration.UserSettings; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Configuration; using System.Collections.Generic; namespace Emby.YouTube.Configuration { public class ConfigurationFactory : IUserConfigurationFactory { public static string ConfigKey = "YTChannel"; public IEnumerable<ConfigurationStore> GetConfigurations() { PluginConfigStore[] array = new PluginConfigStore[1]; PluginConfigStore YTConfigStore = new PluginConfigStore(); YTConfigStore.ConfigurationType = typeof(YTPluginUser); YTConfigStore.Key = ConfigKey; array[0] = YTConfigStore; return array; } } } using Emby.YouTube.Configuration.UserSettings; using MediaBrowser.Model.Plugins; using System; namespace Emby.YouTube.Configuration { public class YTPluginConfiguration : BasePluginConfiguration { public YTPluginUser[] YTPluginUsers { get; set; } = Array.Empty<YTPluginUser>(); } } using System; namespace Emby.YouTube.Configuration.UserSettings { public class YTPluginUser { public string YouTubeUsername { get; set; } public string YouTubePasswordHash { get; set; } public string YouTubeAuthTokenHash { get; set; } } } Then register this in the PluginConfigStore using System; using Emby.YouTube.Configuration.UserSettings; using MediaBrowser.Common.Configuration; namespace Emby.YouTube.Configuration; public class PluginConfigStore : ConfigurationStore, IValidatingConfiguration { public void Validate(object oldConfig, object newConfig) { if (oldConfig is YTPluginUser oldYTUser) { YTPluginUser newYTUser = (YTPluginUser)newConfig; if (!string.Equals(newYTUser.YouTubeUsername, oldYTUser.YouTubeUsername, StringComparison.OrdinalIgnoreCase) || string.IsNullOrEmpty(newYTUser.YouTubeUsername)) { newYTUser.YouTubeUsername = string.Empty; newYTUser.YouTubePasswordHash = string.Empty; } } } } The JS side //EMBY FUNCTIONS async function getUser() { return await ApiClient.getCurrentUserId(); } function fetchExistingConfiguration(userId) { return ApiClient.getTypedUserSettings(userId, 'YTChannel'); } function loadUserConfiguration(userId, view) { fetchExistingConfiguration(userId).then(function (config) { config.LocationsExcluded = config.LocationsExcluded || []; }); } inside the view function return function(view) { view.addEventListener('viewshow', async() => { loading.show(); mainTabsManager.setTabs(this, 0, getTabs); userId = await getUser(); loadUserConfiguration(userId, view); loading.hide(); //other functions to be carried out on load } } That's as far as i've got so far... i've not implemented the c# side for getting configs etc, but that should be pretty straight forward. Anyone let me know if there are ways i can improve this. Cheers Hi, After using EnableInUserMenu, the plugin page can be viewed by user. but it won't work on mobile apps I found trakt works fine on mobile apps, May I ask how to make it happened. new PluginPageInfo { Name = "customcssjs", DisplayName = "Custom Css and JavaScript", EmbeddedResourcePath = GetType().Namespace + ".Configuration.customcssjs.html", EnableInMainMenu = false, EnableInUserMenu = true, IsMainConfigPage = true, MenuIcon = "tune" }, Link to comment Share on other sites More sharing options...
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