text:
Refactor/rethink how duality handles settings

Summary
There are some things that might be improved in the settings department of duality:
First it seems that duality uses 2 approaches to storing settings.

EditorUserData.xml seems to use a completely separate code flow for writing to the settings file in DualityEditorApp.SaveUserData(). The file itself also has 2 <?xml version="1.0" encoding="utf-8"?> which I have never seen before in a single file. Maybe some hack around dockpanel behavior?
Other setting files are using the duality Serializer class to write to the files. They also use the .dat file extension instead of .xml

Second there's not a clear location for where saving and loading is implemented. Sometimes it happens in DualityApp or DualityEditorApp and other times it happens in the settings class itself. I think we might benefit from making a interface with Save and Load methods where these are implemented on the class itself as that would allow us to treat settings in a more generic way (such as here https://github.com/AdamsLair/duality/blob/master/Source/Editor/DualityEditor/DualityEditorApp.cs#L1012) and also clean up some code from the already big  DualityApp and DualityEditorApp classes.
Thirdly because of how the serializer api works atm it always creates a new instance. This makes it impossible to put change events on the settings class itself because then you would also have to resubscribe to those events which kinda defeats the purpose. It might be beneficial if the serializer api could take a already existing instance and update that instance.

Thirdly because of how the serializer api works atm it always creates a new instance. This makes it impossible to put change events on the settings class itself because then you would also have to resubscribe to those events which kinda defeats the purpose. It might be beneficial if the serializer api could take a already existing instance and update that instance.

Yeah, this is a design flaw in the serializer API, but a big one to fix properly. We should skip this for now and just assume the serializer API to be as-is for now. We should track this it in a separate issue though, because it is worth improving here.

Second there's not a clear location for where saving and loading is implemented. Sometimes it happens in DualityApp or DualityEditorApp and other times it happens in the settings class itself. I think we might benefit from making a interface with Save and Load methods where these are implemented on the class itself as that would allow us to treat settings in a more generic way (such as here https://github.com/AdamsLair/duality/blob/master/Source/Editor/DualityEditor/DualityEditorApp.cs#L1012) and also clean up some code from the already big DualityApp and DualityEditorApp classes.

If we use the regular serializer in all cases, we don't need an API or interface for this, but we could still provide one to avoid requiring that knowledge. Maybe have an abstract SettingsContainer base class?

EditorUserData.xml seems to use a completely separate code flow for writing to the settings file in DualityEditorApp.SaveUserData(). The file itself also has 2 <?xml version="1.0" encoding="utf-8"?> which I have never seen before in a single file. Maybe some hack around dockpanel behavior?
Other setting files are using the duality Serializer class to write to the files. They also use the .dat file extension instead of .xml

Yeah, let's switch this to use Duality serializers as well and, I don't know, put the DockPanel XML inside a string or byte[] field or something. Nobody is going to manually adjust this in XML form anyway.
That said, the custom XML approach currently has the advantage that every editor plugin can just read and write arbitrary custom stuff, so when we do switch to Duality serializers, we need to mirror this behavior in a different way.
One way would be to have an abstract SettingsSection base class with the class for EditorUserData storing a dictionary of them, and editor infrastructure asking each of the plugins for theirs (or null to skip). Essentially the same as it is now, only it's not the editor handing over an XElement, but the plugin handing over a SettingsSection. Would require every plugin with settings to have a class for them though, but maybe that's a good idea anyway?
Alternatively, the plugin classes could themselves be serialized, though that (a) requires the existing-instance thing to be implemented and (b) I'm not sure how I feel about the semantic breach we'd introduce by this. A separate class for containing a plugins settings that is serialized as a whole would be a clear separation.

Besides all of this, as briefly mentioned in #852, it could make sense to rename and / or regroup all existing Duality settings. It might make sense to do this separately of any internal API / serialization changes.
So right now we have:

AppData.dat
UserData.dat (and actually DefaultUserData.dat as well!)
ProjectSettings.dat / EditorAppData.dat (depending on the outcome of #852)
EditorUserData.xml
DesignTimeData.dat

I'd propose to rename them like this going forward, in order to provide better hints regarding their contents:

SystemSettings.dat: Internal engine settings that are constant for this game, like rendering config, starting scene, physics settings, etc.
GameOptions.dat: User-configurable settings of the game, like window size, audio volumes, etc.
ProjectSettings.dat: Global project settings for editing purposes, like launcher path.
EditorOptions.dat: User-specific settings of the editor, like window layout, panels configs, etc. - and I'd actually merge DesignTimeData.dat into this, since right now it only contains whether objects are hidden or locked, which is definitely a user-specific setting.

In this naming scheme, I've chosen "Options" to represent things users can adjust as they want, and "Settings" to represent something global, shared, that is not meant for everyone to adjust as they want. "System" also hints at internals not meant to be touched by players and suggests that it's the engine that is configured here, which is exactly what it does. "Project" sets the context of working on something and hints towards editor usage that way.
Or, in a different form:

Constant
Choose your own

Game
SystemSettings
GameOptions

Editor
ProjectSettings
EditorOptions

Thoughts?

Thirdly because of how the serializer api works atm it always creates a new instance. This makes it impossible to put change events on the settings class itself because then you would also have to resubscribe to those events which kinda defeats the purpose. It might be beneficial if the serializer api could take a already existing instance and update that instance.

Yeah, this is a design flaw in the serializer API, but a big one to fix properly. We should skip this for now and just assume the serializer API to be as-is for now. We should track this it in a separate issue though, because it is worth improving here.

Agree.

Second there's not a clear location for where saving and loading is implemented. Sometimes it happens in DualityApp or DualityEditorApp and other times it happens in the settings class itself. I think we might benefit from making a interface with Save and Load methods where these are implemented on the class itself as that would allow us to treat settings in a more generic way (such as here https://github.com/AdamsLair/duality/blob/master/Source/Editor/DualityEditor/DualityEditorApp.cs#L1012) and also clean up some code from the already big DualityApp and DualityEditorApp classes.

If we use the regular serializer in all cases, we don't need an API or interface for this, but we could still provide one to avoid requiring that knowledge. Maybe have an abstract SettingsContainer base class?

We could also use composition:
	public class SettingsContainer<TSettings>
		where TSettings : class, new()
	{
		public event EventHandler Changed;
		public TSettings Value { get; private set; }
		private readonly string path;

		public SettingsContainer(string path)
		{
			this.path = path;
		}

		public void Load()
		{
			this.Value = Serializer.TryReadObject<TSettings>(this.path) ?? new TSettings();
			Changed?.Invoke(this, EventArgs.Empty);
		}

		public void Save()
		{
			Serializer.WriteObject(this.Value, this.path, typeof(XmlSerializer));
		}
	}

The settings class itself will just be a POCO and be wrapped by this class.

EditorUserData.xml seems to use a completely separate code flow for writing to the settings file in DualityEditorApp.SaveUserData(). The file itself also has 2 <?xml version="1.0" encoding="utf-8"?> which I have never seen before in a single file. Maybe some hack around dockpanel behavior?
Other setting files are using the duality Serializer class to write to the files. They also use the .dat file extension instead of .xml

Yeah, let's switch this to use Duality serializers as well and, I don't know, put the DockPanel XML inside a string or byte[] field or something. Nobody is going to manually adjust this in XML form anyway.
That said, the custom XML approach currently has the advantage that every editor plugin can just read and write arbitrary custom stuff, so when we do switch to Duality serializers, we need to mirror this behavior in a different way.
One way would be to have an abstract SettingsSection base class with the class for EditorUserData storing a dictionary of them, and editor infrastructure asking each of the plugins for theirs (or null to skip). Essentially the same as it is now, only it's not the editor handing over an XElement, but the plugin handing over a SettingsSection. Would require every plugin with settings to have a class for them though, but maybe that's a good idea anyway?

I think thats a good idea to always have. Weakly typed settings are just a pain to deal with. Steering users this way is only a good thing.

Alternatively, the plugin classes could themselves be serialized, though that (a) requires the existing-instance thing to be implemented and (b) I'm not sure how I feel about the semantic breach we'd introduce by this. A separate class for containing a plugins settings that is serialized as a whole would be a clear separation.

I would go for the separate class approach because thats easier to do but also like you already pointed out separating these would ensure a clear separation of concerns.

Besides all of this, as briefly mentioned in #852, it could make sense to rename and / or regroup all existing Duality settings. It might make sense to do this separately of any internal API / serialization changes.
So right now we have:

AppData.dat
UserData.dat (and actually DefaultUserData.dat as well!)
ProjectSettings.dat / EditorAppData.dat (depending on the outcome of #852)
EditorUserData.xml
DesignTimeData.dat

I'd propose to rename them like this going forward, in order to provide better hints regarding their contents:

SystemSettings.dat: Internal engine settings that are constant for this game, like rendering config, starting scene, physics settings, etc.
GameOptions.dat: User-configurable settings of the game, like window size, audio volumes, etc.
ProjectSettings.dat: Global project settings for editing purposes, like launcher path.
EditorOptions.dat: User-specific settings of the editor, like window layout, panels configs, etc. - and I'd actually merge DesignTimeData.dat into this, since right now it only contains whether objects are hidden or locked, which is definitely a user-specific setting.

In this naming scheme, I've chosen "Options" to represent things users can adjust as they want, and "Settings" to represent something global, shared, that is not meant for everyone to adjust as they want. "System" also hints at internals not meant to be touched by players and suggests that it's the engine that is configured here, which is exactly what it does. "Project" sets the context of working on something and hints towards editor usage that way.
Or, in a different form:
Constant	Choose your own
Game	SystemSettings GameOptions
Editor	ProjectSettings EditorOptions
Thoughts?

One problem with this naming I see is that its not immediately clear where these settings are used. Is ProjectSettings used for other purposes as well than just the editor? Same with SystemSettings maybe the editor might use that as well? Its not clear from the name.

Constant
Choose your own

GameSettings
GameOptions

EditorSettings
EditorOptions

This makes it clear which one is used by the game and which one is used by the editor and just feels more consistent.

We could also use composition:

Could you give an example what the advantage of this design would be? Because it seems more complex / harder to understand than just deriving from a base class.

One problem with this naming I see is that its not immediately clear where these settings are used. Is ProjectSettings used for other purposes as well than just the editor? Same with SystemSettings maybe the editor might use that as well? Its not clear from the name.
Constant	Choose your own
GameSettings GameOptions
EditorSettings EditorOptions
This makes it clear which one is used by the game and which one is used by the editor and just feels more consistent.

The same thought crossed my mind, but now we have the problem that options and settings are used pretty much synonymously - and I couldn't give an exact definition on when to use each myself. I think we need something else.
How about GameProjectSettings and EditorProjectSettings? Or something along those lines?

We could also use composition:

Could you give an example what the advantage of this design would be? Because it seems more complex / harder to understand than just deriving from a base class.

Some advantages:

Setting class itself is just a POCO.
Allows us to move the change events to the settingcontainer instead of keeping them in DualityApp and DualityEditorApp.
Can use this as a reference to a setting instance, no need to modify the serializer for that.

One problem with this naming I see is that its not immediately clear where these settings are used. Is ProjectSettings used for other purposes as well than just the editor? Same with SystemSettings maybe the editor might use that as well? Its not clear from the name.
Constant	Choose your own
GameSettings GameOptions
EditorSettings EditorOptions
This makes it clear which one is used by the game and which one is used by the editor and just feels more consistent.

The same thought crossed my mind, but now we have the problem that options and settings are used pretty much synonymously - and I couldn't give an exact definition on when to use each myself. I think we need something else.
How about GameProjectSettings and EditorProjectSettings? Or something along those lines?

But the term 'Project' really only makes sense in a editor context (which is probably the reason for your first proposal?). Shipping a GameProjectSettings with the published game to a enduser feels a bit weird.
Maybe we should just stick to the AppData/UserAppData naming scheme. I mean that is a quite standard way of naming this.

Some advantages:

Setting class itself is just a POCO.
Allows us to move the change events to the settingcontainer instead of keeping them in DualityApp and DualityEditorApp.
Can use this as a reference to a setting instance, no need to modify the serializer for that.

Hmm.. honestly, the first two arguments don't sound super convincing to me 😄 (it's just a different design, at least I don't see an inherent advantage there), but you got me with the third one. Since we can't deserialize into an existing settings instance, this is a spot where it could actually help.

Composition is not that hard of a pattern to grasp and widely used. It really is nothing more than wrapping a class with a class (doesn't necessarily need to be a class though) actually as you can see in the draft PR I made. Duality actually already uses composition with for instance ContentRef.

Yeah, though you gotta admit, DualityAppData is just a lot simpler to understand than SettingsContainer<DualityAppData> - now I need to know about two types and their interaction and purposes, and I start to wonder when to wrap and when not to, and so on. Even if widely used, we pay with added complexity, so we should be sure we're getting something nice in return.
Anyway, you're solving an actual issue with this, so I'll stop with the design philosophy right here.

Maybe we should just stick to the AppData/UserAppData naming scheme. I mean that is a quite standard way of naming this.

Alright, let's establish this as a baseline then:

AppData.dat: Internal engine and app settings that are constant for this game, like rendering config, starting scene, physics settings, etc.
UserData.dat: User-configurable settings of the game, like window size, audio volumes, etc.
EditorAppData.dat: Global project and editor settings, like launcher path.
EditorUserData.dat: User-specific settings of the editor, like window layout, panels configs, etc. -with DesignTimeData.dat merged into this, since right now it only contains whether objects are hidden or locked, which is definitely a user-specific setting.

Constant
Choose your own

Game
AppData
UserData

Editor
EditorAppData
EditorUserData

...and we can just all keep in mind that if anyone comes up with something better, we can reconsider this later.

For usability reasons I do think we should stick with .xml extensions though. Editors know what to do with .xml while with .dat you don't get any highlighting.

In that case, the code that serializes any of these settings should choose the XmlSerializer specifically via preferredSerializer, avoiding that any future or project-specific change will cause them to use a different one. Having binary (or something else entirely) in a .xml is not fun 😄

Note: As far as I can see from #856, the file extension change to .xml is done only for the new EditorAppData.xml, while the others still use .dat.
@Barsonax Depending on your plans for that, this could either be done as part of #860, or with a separate PR. Where are we on this overall, and where can others (including me) step in and contribute towards the implementation of this issue?

Extensions are currently changed to xml in #860 actually. Didn't changed them all in #856 due to conflicts.
The PR is still WIP though.

Progress

Updated the core to use Duality Serializers and settings container object for all user and app data via #856
Updated the editor to use Duality Serializers and settings container objects for all user and app data via #865

ToDo

Port a very simple editor plugin to use the new user data handling to ensure the new API is complete and usable, extend and tweak as needed. LogView is probably a good candidate: #868
Port the existing editor plugin user data code to use the new Duality Serializers / settings container based API.

Make sure to use sensible defaults in the settings objects, reflecting the formerly embedded EditorUserData.xml file, which no longer exists.
#866, #867, #869, #870, #871, #872

Remove legacy API for user data serialization.

Worked on the API a bit while looking into #868 and I think we should keep in mind a slight design trap we might fall into:

Even though the EditorPlugin API still suggests some sort of transformation / serialization in Load / Save, we should treat the new settings objects for each plugin as first-class storage where possible, avoiding the need for field assignments entirely in some cases.
UI still needs their update after load, but that should be it.
State retrieval from UI should be avoided for saving, since doing it only on save means that our first-class data object is outdated all the time until then. Instead, state retrieval from the UI into the settings object needs to happen directly when detecting the UI change.
Settings access in plugins should always use the settings object directly, not some UI state.

Worked on the API a bit while looking into #868 and I think we should keep in mind a slight design trap we might fall into:

Even though the EditorPlugin API still suggests some sort of transformation / serialization in Load / Save, we should treat the new settings objects for each plugin as first-class storage where possible, avoiding the need for field assignments entirely in some cases.
UI still needs their update after load, but that should be it.
State retrieval from UI should be avoided for saving, since doing it only on save means that our first-class data object is outdated all the time until then. Instead, state retrieval from the UI into the settings object needs to happen directly when detecting the UI change.
Settings access in plugins should always use the settings object directly, not some UI state.

Agree this will make things cleaner with less steps in between. I just didn't went that far for a first itteration.

Fixed some behavior that was broken during the SettingsContainer refactoring in commits https://github.com/AdamsLair/duality/commit/ea5acb367fd2bcbc06accda76e92ff43b006f1b5 and https://github.com/AdamsLair/duality/commit/1531037d8f57f621e05d69d2079a75a74175afbd. Unfortunately, this invalidates some of the benefits we got through the SettingsContainer abstraction:

The "save-on-change" code now needs to check specific instances again, since there is no way to know which container to save based on just a changed instance.
To re-establish the special case behavior for UserData.xml and DefaultUserData.xml there are now essentially two custom delegates overwriting load and save behavior, similar to how a virtual method overload would.

Both of them can be simplified away in an "abstract settings base class" scenario as opposed to a container design, which we didn't implement before due to the serializers inability to update an existing instance. However, I think we should reconsider this as soon as #877 is addressed.

Progress

Fixed editor settings menus selecting the container object instead of the settings instances directly (see comment above).
Fixed Default/UserData.xml behavior in core and editor (see comment above).
Ported LogViewPlugin settings to the new model (#868) and established "settings object ground truth" design for this and following port PRs (see three comments above).
Ported EditorBasePlugin settings to the new model (#866)
Ported ObjectInspectorPlugin settings to the new model (#871)

ToDo

Port ProjectViewPlugin settings to the new model (#872)
Port TilemapsPlugin settings to the new model (#869)
Consider revisiting CamViewPlugin settings and porting it to the new model as well instead of relying on legacy settings (revisit #867)
Consider merging PluginSettings class into DualityEditorUserData directly, since it's essentially just a wrapper around a List<object> with a utility Get (or create) method, and we do pay for it with a little readability.
Consider removing SettingsContainer<T> design and replacing it with a DualitySettings base class.

Move change events, path info and load / save methods to base class.
Allows to get rid of all .Instance accesses in the codebase and re-generalize the "save-on-change" code in the editor.
Update existing instance on load via workaround mentioned in #877.

Remove legacy API for user data serialization (when made possible by porting all plugins)

EditorPlugin Load / Save methods accepting XElement, as well as GetDefaultUserData method.
EditorPluginManager legacy support code blocks (would turn up as compiler errors anyway).
PluginSettings field and property for old-style data

Progress

Fixed editor settings menus selecting the container object instead of the settings instances directly (see comment above).
Fixed Default/UserData.xml behavior in core and editor (see comment above).
Ported LogViewPlugin settings to the new model (#868) and established "settings object ground truth" design for this and following port PRs (see three comments above).
Ported EditorBasePlugin settings to the new model (#866)
Ported ObjectInspectorPlugin settings to the new model (#871)

ToDo

Port ProjectViewPlugin settings to the new model (#872)

Port TilemapsPlugin settings to the new model (#869)

Consider revisiting CamViewPlugin settings and porting it to the new model as well instead of relying on legacy settings (revisit #867)

Consider merging PluginSettings class into DualityEditorUserData directly, since it's essentially just a wrapper around a List<object> with a utility Get (or create) method, and we do pay for it with a little readability.

Consider removing SettingsContainer<T> design and replacing it with a DualitySettings base class.

Move change events, path info and load / save methods to base class.
Allows to get rid of all .Instance accesses in the codebase and re-generalize the "save-on-change" code in the editor.
Update existing instance on load via workaround mentioned in #877.

Remove legacy API for user data serialization (when made possible by porting all plugins)

EditorPlugin Load / Save methods accepting XElement, as well as GetDefaultUserData method.
EditorPluginManager legacy support code blocks (would turn up as compiler errors anyway).
PluginSettings field and property for old-style data

Reconsider settings change handling in the editor.

Changes should not be saved in every single PropertyChanged event, but in the next "save all" action.

Changes should probably (?) be applied either after every PropertyChanged event, because it would be inconsistent if the value is already there, but no system relying on it got a chance to update, so only those not needing one will use the current value.

Need to be careful as to where Apply might trigger a lot of work. It's probably fine, but should be tested thoroughly, with a game in the sandbox and a real project to test. Maybe the DualStickSpaceShooter sample.

The now-merged DesignTimeObjectDataManager should probably use its custom serialization to store its data in a byte[] to avoid giant EditorUserData XMLs when lots of objects are hidden or locked. As far as I know, the custom per-object user data was never used, ever, and could be removed for now to greatly simplify this.

Hey, im interessted how far you guys pushed Duality to bring it closer to 4.0 version, Well done, how far did you come with the settings change tho?

I'm currently more or less in hibernation mode due to daily workload in non-OSS domains, but current progress and ToDo as documented here should be up-to-date. @Barsonax might know more, in case there are more recent changes, if any.

authors: Barsonax Shpendicus ilexp

repo: AdamsLair/duality


text:
DockState<Tab>::remove_tab may cause the whole program panic when the tab is the last tab of a window.

Describe the bug
when use remove_tab function to remove the last tab from a window, it could not close the window like clicking on the tab.
And in the next time I call egui_dock::DockArea::show_inside, the program panic.
To Reproduce
Steps to reproduce the behavior:
match self.tree.find_tab(&tab) {
                        Some(index) => {
                            self.tree.remove_tab(index);
                        }
                        None => {
                            self.tree.add_window(vec![tab]);
                        }
                    }

Is there any way to close the tab from rust code just like what it happens when I click the close button?

Is there any way to close the tab from rust code just like what it happens when I click the close button?

Yes, you can override TabViewer::force_close.

This function works. Thanks very much.

Now to actually fix the issue: looks like tabs in windows aren't correctly deleted with DockState::remove_tab, leaving a Surface without a leaf node. We need to also delete the surface when that happens.

source: gharchive/issue

license: MIT

license_type: permissive

license_source: github-api


text:
Different design: more compact windows and collapsing/closing control on each tab bar

Resolves #238. See the issue for a full discussion of this design.
Here's a list of technically missing features in this PR, but I'd like to hear some opinions before carrying on ;)

[x] Proper styling (especially rounding)

After careful checking of the design, this should be done on the user side.

[x] Dragging tabs to an empty space on the main surface (https://github.com/Adanos020/egui_dock/pull/237/commits/fd805c924e2febed9bebee02c338d3ee0bf840cd, https://github.com/Adanos020/egui_dock/pull/237/commits/ccce02f21005aada100e33c47a6b00c5b4d55e1b)
[x] Dragging tabs to a collapsed Leaf (https://github.com/Adanos020/egui_dock/pull/237/commits/fd805c924e2febed9bebee02c338d3ee0bf840cd, https://github.com/Adanos020/egui_dock/pull/237/commits/ccce02f21005aada100e33c47a6b00c5b4d55e1b)
[x] Proper CHANGELOG (https://github.com/Adanos020/egui_dock/pull/237/commits/370e477ff33af9565bed560b3c23f9cfdf6aa7a5)
[x] Update examples (https://github.com/Adanos020/egui_dock/pull/237/commits/6e56846f1203627b17fb2d12c480c380676ec13f)

Hi, sorry for the massive delay! My irl stuff has been insane in the last couple of months.
I think the features you've added are great, although I think having a button that lets you collapse a whole window (which we lost in this PR) would be really nice to have. Can we add it back?
I've fixed up a few things following the release of 0.13 and rebasing to the next release branch. Let me know if there's anything I could help you with.

I think having a button that lets you collapse a whole window (which we lost in this PR) would be really nice to have.

I'd be glad to add this feature, but I'm unsure how we should design this. Should collapsing a whole window be:

a shortcut that simply collapses all leaf subnodes (i.e. the collapsed window may still have multiple tab bars), or
a feature that turns the window into a dedicated state that only have a single line (so really compact)?

if this is preferred, what should be displayed on the single line? Active node name like the original design, or just a simple count label like "3 tabs, 2 leafs", or anything better?
noting that we are no longer using collapsing headers, so some tweaking may needed.

@Adanos020 I've implemented this feature like this:
https://github.com/Adanos020/egui_dock/assets/68492819/7f86e70b-9049-4726-a405-d1a20c782183
So essentially all features available in the original design is now in the right-click context menu of the relevant buttons.

@micfong-z This looks good, although it isn't immediately obvious that you can right-click on the buttons. I reckon a tooltip on each button could help with that.

@Adanos020 Done – I've also fixed cargo test. I reckon another design of activating these features by shift-clicking (or ctrl/alt/...-clicking?) the buttons might be possible, but I'm not really sure if this applies well to different keyboard layouts, or if this is even more obscured.

That sounds good, I'd say let's come up with a few designs and let the library users choose.
One design I've been thinking of is to have separate buttons for windows, but make them look like little bookmarks behind the window (or the tab bar) that'll pull out when you hover over them. How does that sound?

That design sounds brilliant! Though I would have to dig deep enough to figure out a way to display some sort of floating panels behind windows. AFAIK, since all Areas in egui are rectangular, these floating panels may mean introducing two auxiliary windows for each window.... I'll give it a try anyways :/

Sorry for not being active on this PR recently due to ... irl stuff ( :( ) – but I think I've caught up a bit.
For now I have implemented the two options I've mentioned for the user to choose (modifier key method and context menu method), but I've been really struggling to get the bookmark button method done.
I have experimented with creating new Areas, tweaking Tooltips, or even creating auxiliary Windows, but all of them have issues with at least one of focusing, anchoring and layering. ChatGPT and Googling didn't help (of course), and the codebase and changelog is getting a bit messy.
I'd be happy to carry on experimenting if someone could give me some directions to work on. Nevertheless, this feature could probably be put in a separate PR instead considering its complexity.
@Adanos020 if creating a separate PR for this specific issue is okay, I'll go on finalizing/cleaning up the codebase then!

Hey, no worries at all, I've also been dealing with lots of personal issues because of which I didn't have much time to dedicate to this project. Thanks for coming back to this PR!
If the bookmark button is too big of a pain to implement, then I'd say let's drop it for now. We can make do with the current designs.

@Adanos020 Everything is good to go now (from my side), but I'll point out a few possible caveats

the translation examples in lib.rs are translated from an online service, so no guarantee that they would be fully correct
I used the term "leaf" for ... Leafs on user-side tooltips. Not sure if this would be confusing.

Thanks for merging! A side note for consistency in JP translations: the lines ending with 。 (CN/JP full stop) are all tooltip texts, so keeping them at the end is more consistent with English/Polish translations.
However, as per Material Design Guidelines, the full stops should not follow single-sentence tooltip texts. Maybe remove all full stops in translations would be good.

source: gharchive/pull-request


text:
Adding 2 numbers witout using + operator

rj011 /  Add 2 numbers in js without the + operator- a recursive approach / 13-10-22

Hello sir, please assign this issue to me as i already worked on this kind of project in past and has a great experience.


text:
ADLDAP_ACCOUNT_SUFFIX doesn't work

Laravel Version: 5.6
Adldap2-Laravel Version: 3.0
PHP Version: 7.2
LDAP Type: ActiveDirectory

Description:
Hello, Guys
First of all, I want you to congrats for this exceptional code. I know it'll help me a lot with my Laravel projects. I make one but I actually have a problem whit the ADLDAP_ACCOUNT_SUFFIX config in my .dev file
I can do login with my ActiveDirectory because I follow this instructions: https://github.com/Adldap2/Adldap2-Laravel/blob/master/docs/quick-start.md
But if I have my .env file whitout the config ADLDAP_ACCOUNT_SUFFIX I have to put in my login form username@mydomain.local
If I put the ADLDAP_ACCOUNT_SUFFIX in my .env file and I put in my login form username It doesn't work...I need your help because is a bad think tell my users they need to use username@mydomain.local when they need to sing in to my app.
I attach my actually conf files:
adlap_auth.php
<?php

return [
    'connection' => env('ADLDAP_CONNECTION', 'default'),
    'provider' => Adldap\Laravel\Auth\DatabaseUserProvider::class,
    'rules' => [
        Adldap\Laravel\Validation\Rules\DenyTrashed::class,
    ],
    'scopes' => [
        Adldap\Laravel\Scopes\UpnScope::class,
    ],
    'usernames' => [
        'ldap' => [
            'discover' => 'userprincipalname',
            'authenticate' => 'distinguishedname',
        ],
        'eloquent' => 'username',
        'windows' => [
            'discover' => 'samaccountname',
            'key' => 'AUTH_USER',
        ],
    ],
    'passwords' => [
        'sync' => env('ADLDAP_PASSWORD_SYNC', false),
        'column' => 'password',
    ],
    'login_fallback' => env('ADLDAP_LOGIN_FALLBACK', false),
    'sync_attributes' => [
        'username' => 'userprincipalname',
        'name' => 'cn',
    ],
    'logging' => [
        'enabled' => true,
        'events' => [
            \Adldap\Laravel\Events\Importing::class => \Adldap\Laravel\Listeners\LogImport::class,
            \Adldap\Laravel\Events\Synchronized::class => \Adldap\Laravel\Listeners\LogSynchronized::class,
            \Adldap\Laravel\Events\Synchronizing::class => \Adldap\Laravel\Listeners\LogSynchronizing::class,
            \Adldap\Laravel\Events\Authenticated::class => \Adldap\Laravel\Listeners\LogAuthenticated::class,
            \Adldap\Laravel\Events\Authenticating::class => \Adldap\Laravel\Listeners\LogAuthentication::class,
            \Adldap\Laravel\Events\AuthenticationFailed::class => \Adldap\Laravel\Listeners\LogAuthenticationFailure::class,
            \Adldap\Laravel\Events\AuthenticationRejected::class => \Adldap\Laravel\Listeners\LogAuthenticationRejection::class,
            \Adldap\Laravel\Events\AuthenticationSuccessful::class => \Adldap\Laravel\Listeners\LogAuthenticationSuccess::class,
            \Adldap\Laravel\Events\DiscoveredWithCredentials::class => \Adldap\Laravel\Listeners\LogDiscovery::class,
            \Adldap\Laravel\Events\AuthenticatedWithWindows::class => \Adldap\Laravel\Listeners\LogWindowsAuth::class,
            \Adldap\Laravel\Events\AuthenticatedModelTrashed::class => \Adldap\Laravel\Listeners\LogTrashedModel::class,
        ],
    ],
];

adldap.php
<?php

return [
    'connections' => [
        'default' => [
            'auto_connect' => env('ADLDAP_AUTO_CONNECT', true),
            'connection' => Adldap\Connections\Ldap::class,
            'schema' => Adldap\Schemas\ActiveDirectory::class,
            'connection_settings' => [
                'account_prefix' => env('ADLDAP_ACCOUNT_PREFIX', ''),
                'account_suffix' => env('ADLDAP_ACCOUNT_SUFFIX', ''),
                'domain_controllers' => explode(' ', env('ADLDAP_CONTROLLERS', 'corp-dc1.corp.acme.org corp-dc2.corp.acme.org')),
                'port' => env('ADLDAP_PORT', 389),
                'timeout' => env('ADLDAP_TIMEOUT', 5),
                'base_dn' => env('ADLDAP_BASEDN', 'dc=corp,dc=acme,dc=org'),
                'admin_account_prefix' => env('ADLDAP_ADMIN_ACCOUNT_PREFIX', ''),
                'admin_account_suffix' => env('ADLDAP_ADMIN_ACCOUNT_SUFFIX', ''),
                'admin_username' => env('ADLDAP_ADMIN_USERNAME', 'username'),
                'admin_password' => env('ADLDAP_ADMIN_PASSWORD', 'password'),
                'follow_referrals' => false,
                'use_ssl' => env('ADLDAP_USE_SSL', false),
                'use_tls' => env('ADLDAP_USE_TLS', false),
            ],
        ],
    ],
];

.env
ADLDAP_CONTROLLERS=myActiveDirectoryIP
ADLDAP_BASEDN="dc=mydomain,dc=local"
ADLDAP_ACCOUNT_SUFFIX=@mydomain.local //doesn't work (this is what I want)

ADLDAP_ADMIN_USERNAME=admin
ADLDAP_ADMIN_PASSWORD=secret
ADLDAP_ADMIN_ACCOUNT_SUFFIX=@mydomain.local

MyLoginForm
@extends('layouts.app')

@section('content')

{{ __('Login') }}

                    <form method="POST" action="{{ route('login') }}">
                        @csrf

                            {{ __('Username') }}

                                <input id="username" type="text" class="form-control{{ $errors->has('username') ? ' is-invalid' : '' }}" name="username" value="{{ old('username') }}" required autofocus>

                                @if ($errors->has('username'))

                                        {{ $errors->first('username') }}

                                @endif

                            {{ __('Password') }}

                                <input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>

                                @if ($errors->has('password'))

                                        {{ $errors->first('password') }}

                                @endif

                                        <input type="checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}> {{ __('Remember Me') }}

                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>

                                    {{ __('Forgot Your Password?') }}

                    </form>

@endsection

Thank you very much for your help.
I apologize for my bad English...I wish you could understand what I want and what is not working...

Hello,
on this part I set both to samaccountname and it worked in my environment:
'usernames' => [
'ldap' => [
'discover' => 'userprincipalname',
'authenticate' => 'distinguishedname',
Maybe you it works for you.
Nico

Hello, Nico
Thank you for comment...When I do that I get another error (something I use to) the code try to insert again my user data and my database get an error because username is unique...The exact error is: Integrity constraint violation: 1062 Duplicate entry for mi account...
Brian

Hi @briancardonas, what database are you using?
If you're using Postgre or other case-sensitive databases, you need to call strtolower() on usernames prior to authenticating users.

Hi @stevebauman,
I'm using MySQL and the problem is when I try to autenticate my users using ADLDAP_ACCOUNT_SUFFIX in my .env file It doesn't work I need to override login action to make it works...But...In my opinion I'll prefered if the ADLDAP_ACCOUNT_SUFFIX work's
public function login(Request $request) {
$credentials` = $request->only('username', 'password');
['username'] = $credentials['username'].'@mydomain.local';
(Auth::attempt($credentials)) {
redirect()->route('home');
}
}

I am also experiencing this same issue with my application on a MYSQL database.

I'm new to this framwork and I can confirm I have the same problem. It works perfectly for the admin suffix but the user suffix won't authenticate the user.

Would be great if this did a simple Str::finish() to append the domain so I can search with userPrincipalName and allow short or long logins.

Hi @murrant,
Mind sending a PR so I know what you mean for implementation?

I haven't gotten that far yet, need adldap2 working in my project first.

authors: FrancisBou briancardonas dotmiikee murrant nicro87 stevebauman


text:
[SECURITY] Fix Temporary File Information Disclosure Vulnerability

Security Vulnerability Fix
This pull request fixes a Temporary File Information Disclosure Vulnerability, which existed in this project.
Preamble
The system temporary directory is shared between all users on most unix-like systems (not MacOS, or Windows). Thus, code interacting with the system temporary directory must be careful about file interactions in this directory, and must ensure that the correct file posix permissions are set.
This PR was generated because a call to File.createTempFile(..) was detected in this repository in a way that makes this project vulnerable to local information disclosure.
With the default uname configuration, File.createTempFile(..) creates a file with the permissions -rw-r--r--. This means that any other user on the system can read the contents of this file.
Impact
Information in this file is visible to other local users, allowing a malicious actor co-resident on the same machine to view potentially sensitive files.
Other Examples

CVE-2020-15250 - junit-team/junit
CVE-2021-21364 - swagger-api/swagger-codegen
CVE-2022-24823 - netty/netty
CVE-2022-24823 - netty/netty

The Fix
The fix has been to convert the logic above to use the following API that was introduced in Java 1.7.
File tmpDir = Files.createTempFile("temp dir").toFile();

The API both creates the file securely, ie. with a random, non-conflicting name, with file permissions that only allow the currently executing user to read or write the contents of this file.
By default, Files.createTempFile("temp dir") will create a file with the permissions -rw-------, which only allows the user that created the file to view/write the file contents.
:arrow_right: Vulnerability Disclosure :arrow_left:
:wave: Vulnerability disclosure is a super important part of the vulnerability handling process and should not be skipped! This may be completely new to you, and that's okay, I'm here to assist!
First question, do we need to perform vulnerability disclosure? It depends!

Is the vulnerable code only in tests or example code? No disclosure required!
Is the vulnerable code in code shipped to your end users? Vulnerability disclosure is probably required!

Vulnerability Disclosure How-To
You have a few options options to perform vulnerability disclosure. However, I'd like to suggest the following 2 options:

Request a CVE number from GitHub by creating a repository-level GitHub Security Advisory. This has the advantage that, if you provide sufficient information, GitHub will automatically generate Dependabot alerts for your downstream consumers, resolving this vulnerability more quickly.
Reach out to the team at Snyk to assist with CVE issuance. They can be reached at the Snyk's Disclosure Email.

Detecting this and Future Vulnerabilities
This vulnerability was automatically detected by GitHub's CodeQL using this CodeQL Query.
You can automatically detect future vulnerabilities like this by enabling the free (for open-source) GitHub Action.
I'm not an employee of GitHub, I'm simply an open-source security researcher.
Source
This contribution was automatically generated with an OpenRewrite refactoring recipe, which was lovingly hand crafted to bring this security fix to your repository.
The source code that generated this PR can be found here:
SecureTempFileCreation
Opting-Out
If you'd like to opt-out of future automated security vulnerability fixes like this, please consider adding a file called
.github/GH-ROBOTS.txt to your repository with the line:
User-agent: JLLeitschuh/security-research
Disallow: *

This bot will respect the ROBOTS.txt format for future contributions.
Alternatively, if this project is no longer actively maintained, consider archiving the repository.
CLA Requirements
This section is only relevant if your project requires contributors to sign a Contributor License Agreement (CLA) for external contributions.
It is unlikely that I'll be able to directly sign CLAs. However, all contributed commits are already automatically signed-off.

The meaning of a signoff depends on the project, but it typically certifies that committer has the rights to submit this work under the same license and agrees to a Developer Certificate of Origin
(see https://developercertificate.org/ for more information).
- Git Commit Signoff documentation

If signing your organization's CLA is a strict-requirement for merging this contribution, please feel free to close this PR.
Sponsorship & Support
This contribution is sponsored by HUMAN Security Inc. and the new Dan Kaminsky Fellowship, a fellowship created to celebrate Dan's memory and legacy by funding open-source work that makes the world a better (and more secure) place.
This PR was generated by Moderne, a free-for-open source SaaS offering that uses format-preserving AST transformations to fix bugs, standardize code style, apply best practices, migrate library versions, and fix common security vulnerabilities at scale.
Tracking
All PR's generated as part of this fix are tracked here: https://github.com/JLLeitschuh/security-research/issues/18

Hi
Do you believe this fixed a valid security vulnerability? Do you need assistance with vulnerability disclosure and CVE issuance?

license_source: bigquery


text:
PR Checker Mac node fails check due to having xcode 12

test suite/name - macOS (jdk8u, hotspot) (PR checker)
Is there an existing issue elsewhere covering this - Not that I can find.
Which machine(s) does it work on? - Unable to find reproduction elsewhere.
Which machine(s) does it fail on? - Unable to find node name in output
Do you have a link to a Grinder re-run if the test with the failure? - No.

Any other details:
Failure link: https://github.com/adamfarley/openjdk-build/runs/1328981562?check_suite_focus=true
Error message:
checking for xcodebuild... /usr/bin/xcodebuild
configure: error: Xcode 4, 9, 10 or 11 is required to build JDK 8, the version found was 12.0.1. Use --with-xcode-path to specify the location of Xcode or make Xcode active by using xcode-select.
configure exiting with result code 1
Makefile:55: *** Cannot continue.  Stop.

Also, this issue appears to state that all Macs should use Xcode 10 by default (unless that's changed in the last 4 months). So I'm assuming this error is a config bug for this one machine.
https://github.com/AdoptOpenJDK/openjdk-infrastructure/issues/1400

Happened again: https://github.com/AdoptOpenJDK/openjdk-build/runs/1329173922?check_suite_focus=true

Working on a fix: https://github.com/AdoptOpenJDK/openjdk-build/pull/2197. More info in the PR.

authors: aahlenst adamfarley

repo: AdoptOpenJDK/openjdk-infrastructure


text:
jdk-13+33 mac jvm_net B8185898 test failure

https://ci.adoptopenjdk.net/job/Test_openjdk13_hs_sanity.openjdk_x86-64_mac/53/console
Machine: test-macincloud-macos1014-x64-1
Version: 13+33
13:57:22  java.lang.AssertionError: FAILED: expected: This /is/a/fake/status/line HTTP/2.0
13:57:22  X-header1: This test value should appear
13:57:22  X-header2: This test value should appear
13:57:22  This is not a request line for HTTP/1.1:
13:57:22
13:57:22
13:57:22  Received: This /is/a/fake/status/line HTTP/2.0
13:57:22  X-header1: This test value should appear
13:57:22  X-header2: This test value should appear
13:57:22  This is not a request line for HTTP/1.1
13:57:22
13:57:22
13:57:22  	at B8185898.testMessageHeader(B8185898.java:133)
13:57:22  	at B8185898.main(B8185898.java:104)
13:57:22  	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
13:57:22  	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
13:57:22  	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
13:57:22  	at java.base/java.lang.reflect.Method.invoke(Method.java:567)
13:57:22  	at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:127)
13:57:22  	at java.base/java.lang.Thread.run(Thread.java:830)
13:57:22
13:57:22  JavaTest Message: Test threw exception: java.lang.AssertionError: FAILED: expected: This /is/a/fake/status/line HTTP/2.0
13:57:22  X-header1: This test value should appear
13:57:22  X-header2: This test value should appear
13:57:22  This is not a request line for HTTP/1.1:
13:57:22
13:57:22
13:57:22  Received: This /is/a/fake/status/line HTTP/2.0
13:57:22  X-header1: This test value should appear
13:57:22  X-header2: This test value should appear
13:57:22  This is not a request line for HTTP/1.1

https://github.com/AdoptOpenJDK/openjdk-tests/pull/1357

repo: AdoptOpenJDK/openjdk-tests


text:
RUIMTEDETAILSOORT.GTU is twee keer gedefinieerd

Er zijn twee definities voor RUIMTEDETAILSOORT.GTU met als parent RUIMTESOORT.GEM. Deze hebben als naam Gemeenschappelijke tuin en Gemeenschappelijk dakterras
https://github.com/Aedes-datastandaarden/vera-referentiedata/blob/475676fe7fc98ecc6d2a0d9a88fd239623692b8d/Referentiedata.csv#L1719-L1720
Mogelijk gerelateerd aan andere definitie met als naamGemeenschappelijk dakterras en parent RUIMTESOORT.BTR
https://github.com/Aedes-datastandaarden/vera-referentiedata/blob/475676fe7fc98ecc6d2a0d9a88fd239623692b8d/Referentiedata.csv#L1715

Goedemorgen Ben, Dank voor je input. Wij gaan dit vandaag met een patch oplossen. Met vriendelijke groet, VERA-architectuurteam

authors: MarcelVanDenBos benverhees


text:
Make the Rust and OCaml name matchers consistent with each other

The Rust and OCaml name matchers have quite a few differences: it may be good to reduce the gap.
For instance, adding the syntax impl ... for ... for the OCaml name matcher is a good idea.

Noting here so we don't forget: we likely want impl ... for .. to only match traits while impl ... can match both traits and types.

authors: Nadrieril sonmarcho

repo: AeneasVerif/charon


text:
Removed redundant ecr_repo_name from README

[ ] I have added the tests to cover my changes.
[ ] I have updated the documentation and CHANGELOG accordingly.
[ ] I have read the CONTRIBUTING document.

@AlejandroEsquivel Merge this PR first to fix the pre-commit action: https://github.com/AgnostiqHQ/covalent-ecs-plugin/pull/60

authors: AlejandroEsquivel FyzHsn

repo: AgnostiqHQ/covalent-ecs-plugin


text:
"export 'requireNativeComponent' was not found in 'react-native-web/dist/index'

./node_modules/react-native-agora/lib/module/common/RtcRenderView.native.js:102:26
"export 'requireNativeComponent' was not found in 'react-native-web/dist/index'
100 |  * @ignore
101 |  */

102 | const RCTRtcTextureView = requireNativeComponent(
|                          ^
103 |   'RCTAgoraRtcTextureView'
104 | );
105 |

Got this error message. I'm using following setup.

 "dependencies": {
    "@react-native-masked-view/masked-view": "0.2.6",
    "@react-navigation/native": "^6.0.6",
    "@react-navigation/stack": "^6.0.11",
    "agora-rn-uikit": "^3.3.0",
    "axios": "^0.24.0",
    "expo": "~44.0.0",
    "expo-dev-client": "^0.8.0",
    "expo-status-bar": "~1.2.0",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-native": "0.64.3",
    "react-native-agora": "^3.5.1",
    "react-native-gesture-handler": "^1.10.3",
    "react-native-safe-area-context": "3.3.2",
    "react-native-screens": "~3.10.1",
    "react-native-web": "0.17.1"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@types/react": "~17.0.21",
    "@types/react-native": "~0.64.12",
    "typescript": "~4.3.5"
  },

the project was setup using expo, the newest configuration. probably some compatibility issues. I tried to down grade agora to lower version, same issue. maybe beause the react is too new? 17.0.1
using m1 macbook air

oh shoot, eject first

Our package does not support react-native-web

repo: AgoraIO-Community/react-native-agora


text:
Contribution

Hi I would like to contribute to the project! This is awesome. I have written a small function called createfields that follows your other codes convention  to generate schema.json for admin based on prisma schema. Any guidelines of styles to send a pull request with new features?

You can send your pull request and add descriptions for your add i will see if it’s help or not then i will test it if everything is good will merge it
Thanks for your work

authors: AhmedElywa wuichen

repo: AhmedElywa/prisma-tools


text:
DropdownButtonFormField2 | Error border not showing using fillColor

I'm using filled: true and set fillColor to white.
When form validation getting error it's not showing error border.
Packager version:
dropdown_button2: ^3.0.0-beta.17
Example Code:
    DropdownButtonFormField2<String>(
      isExpanded: true,
      valueListenable: valueListenable,
      onChanged: (value) {
        valueListenable.value = value;
      },
      hint: Text('Select Item'),
      items: items.map((String item) => DropdownItem<String>(
          value: item,
          child: Text(item),
        ),
      ).toList(),
      decoration: InputDecoration(
        filled: true,
        fillColor: Colors.white,
        contentPadding: const EdgeInsets.symmetric(vertical: 10),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: BorderSide.none,
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: const BorderSide(color: Colors.green, width: 2),
        ),
        errorBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: const BorderSide(color: Colors.red, width: 2),
        ),
        focusedErrorBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: const BorderSide(color: Colors.red, width: 2),
        ),
      ),
      validator: (String? value) {
        return (value == null || value.isEmpty) ? 'This field is required' : null;
      },
    )

@AhmedLSayed9 Could you please take a look at this issue?

It's the same as #297. I'll fix it in a few days.

@chayanforyou
It should work fine now at latest beta version.


text:
[需求]能不能加个功能，每天晚上查询当天预约结果信息并推送结果

能不能加个功能，每天晚上查询当天预约结果信息并推送结果

”当天预约结果信息“是说有没有中签吗？还是单纯的有没有预约？

有没有中签，不然还要每天打开APP看中签结果

有没有中签，不然还要每天打开APP看中签结果

等我有空再看看能不能抓到对应的包再说。

中奖会发送短信，没中就不会发，没必要搞通知

authors: AkenClub Dlian-Zero Shuai-S

repo: AkenClub/ken-iMoutai-Script


text:
CI: add .cirrus.yml

Fix #94

default.yaml is still tested on macOS instances of GHA
Other yamls are tested on Linux instances of Cirrus. macOS instances of Cirrus cannot be used due to lack of support for nested VMs.

Unlike GHA, Cirrus allows restarting an individual failed test.

Cirrus doesn't seem to support running multiple macOS VMs simultaneously, so maybe worse than GHA
https://cirrus-ci.org/faq/#are-there-any-limits

Maybe we can use Cirrus with multiple nestable Linux VMs to test examples/*.yaml and a single macOS VM to test examples/default.yaml

$ uname -a
Darwin admins-Mac.local 20.3.0 Darwin Kernel Version 20.3.0: Thu Jan 21 00:07:06 PST 2021; root:xnu-7195.81.3~1/RELEASE_X86_64 x86_64

$ sysctl machdep.cpu.features
machdep.cpu.features: FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA CMOV PAT PSE36 CLFSH MMX FXSR SSE SSE2 SS HTT SSE3 PCLMULQDQ MON SSSE3 FMA CX16 SSE4.1 SSE4.2 x2APIC MOVBE POPCNT AES VMM PCID XSAVE OSXSAVE TSCTMR AVX1.0 RDRAND F16C

The macOS instances of Cirrus do not seem to support nested VM (VMX) 😞

Cirrus seems as flaky as GHA, so the only advantage I see is that it has "Re-run" button for individual tests.
@jandubois WDYT?

I do like being able to re-run individual tests, but that really is also just a bandaid for the flaky runners.
Maybe try running all the non-default integration tests with GHA on Ubuntu instead of macOS? I think the macOS runners are especially flaky.
I found some hint that Github was doing some infrastructure migration that should just be completed about now, that should improve macOS runners: https://github.com/actions/virtual-environments/issues/2707#issuecomment-782056996. That was about slow I/O performance, but it sounds like they were doing bigger changes and maybe they are not quite there yet.

Linux instances of GHA do not support nested virtualization AFAIK

Linux instances of GHA do not support nested virtualization AFAIK

Yes, you are right; my bad!
/me sighs

I’m merging this, but we can revert if this does not work as we expect

authors: AkihiroSuda jandubois

repo: AkihiroSuda/lima


text:
How To Allow For Self-Signed SSL Certificates

I have an RxSwift IOS app (Alamofire 4.2.0, Moya 8.0.1) which must connect to multiple home automation controllers - each having their own self-signed certificate (and no there's no way to enforce that my IOS app users install a trusted SSL cert).  According to the ATS documentation my configuration is correct so it's not an ATS issue.  I filed an issue with Moya and attempted several suggestions (e.g. ServerTrustManager) without any luck.
Here's the error message I get from Moya:

underlying(Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={_kCFStreamErrorCodeKey=-9806, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x61800005b3c0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9806, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9806}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made.

@camcoding  你好，请问这个问题解决了吗？

Looks like you got it fixed in the Moya issue. In the future, you should open questions like this on Stack Overflow and tag alamofire.
Cheers. 🍻

From our Contribution Guidelines
Asking Questions
We don't use GitHub as a support forum. For any usage questions that are not specific to the project itself, please ask on Stack Overflow instead. By doing so, you'll be more likely to quickly solve your problem, and you'll allow anyone else with the same question to find the answer. This also allows maintainers to focus on improving the project for others.

authors: LvJianfeng camcoding jshier

repo: Alamofire/Alamofire


text:
Download a PDF from a URL with dynamic response (sometimes PDF, sometimes HTML)

Hi,
I'm using Alamofire 3.5.1 on iOS 10.
We have and endpoint at our backend that sometimes responds with a HTML page, and sometimes with a PDF file. I want to be able to download the PDF file when the content is PDF.
In order to know the content type I first call:
Alamofire.request(.GET, "https://my/REST/endpoint/").responseString { response in
    if let contentType = response.response?.allHeaderFields["Content-Type"] as? String {
    }
}

Inside the completion block I can determine whether we have a "application/pdf" or "html/text" content.
Now, when there is a PDF, I'd like to download it. I'm using:
let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask)
Alamofire.download(.GET, "https://my/REST/endpoint/", destination: destination).response { _, _, _, error in
    if let error = error {
        print("Failed with error: \(error)")
    } else {
        print("Downloaded file successfully")
    }
}

I'm getting an error:
FAILURE: Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x60000084d3b0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x6000002986a0 [0x10a3eedf0]>{length = 16, capacity = 16, bytes = 0x100201bb681932210000000000000000}}}, NSErrorFailingURLStringKey=https://my/REST/endpoint/, NSErrorFailingURLKey=https://my/REST/endpoint/, NSLocalizedDescription=The network connection was lost.}

Strangely, when I use a URL pointing to pdf with extension (https://path.to.site/file.pdf), it works fine. But with our dynamic content URL it doesn't.
Any ideas on how can I use Alamofire to get the PDF file?
UPDATED: Using NSURLSession with a download data task gives the same error "The network connection was lost".
Thanks,
Robert.

The issue was at our backend. Sorry to bother you guys.
And thanks for this awesome framework!


text:
Item with the same name already exists

Hi,
I try to download a file. But I get the error "item with the same name already exists".
How can I resolved that ?
Thank you !
Here my code :
func load(urlString : String) {
    let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask)
    Alamofire.download(.GET, urlString, destination: destination)
        .progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
            //print(totalBytesRead)

            // This closure is NOT called on the main queue for performance
            // reasons. To update your ui, dispatch to the main queue.
            dispatch_async(dispatch_get_main_queue()) {
                print("Total bytes read on main queue: \(totalBytesRead) / \(totalBytesExpectedToRead)")
            }
        }
        .response { _, _, _, error in
            if let error = error {
                print("Failed with error: \(error)")
            } else {
                print("Downloaded file successfully")
            }
    }
}

Failed with error: Error Domain=NSCocoaErrorDomain Code=516 "“CFNetworkDownload_gVZNJr.tmp” couldn’t be moved to “Documents” because an item with the same name already exists." UserInfo={NSSourceFilePathErrorKey=/Users/macbook_pro/Library/Developer/CoreSimulator/Devices/41698325-FC7D-40FD-B6BA-4E5651736E49/data/Containers/Data/Application/2735D05C-AAB4-4777-BDBA-5BE8125F7C49/tmp/CFNetworkDownload_gVZNJr.tmp,

You need to delete the file first before you re-download it. The moveItemAtURL(:toURL:) is failing.

How can I delete it ?

@xero88 you can do something like this..
let url = NSUrl(string: "...")
if NSFileManager.defaultManager().fileExistsAtPath(url.path!) {
    try! NSFileManager.defaultManager().removeItemAtURL(url)
}

@katunch thank you for your answer
but suggestedDownloadDestination return a typealias :
public typealias DownloadFileDestination = (NSURL, NSHTTPURLResponse) -> NSURL
How can I cast it to NSURL ?

I did it this way, because i know the filename already.
let destination: (NSURL, NSHTTPURLResponse) -> (NSURL) = {
    (temporaryUrl, response)  in
    if response.statusCode == 200 {
        if NSFileManager.defaultManager().fileExistsAtPath(ProfitApp.JsonUrl.path!) {
            try! NSFileManager.defaultManager().removeItemAtURL(ProfitApp.JsonUrl)
        }
        return ProfitApp.DocumentDirectoryUrl.URLByAppendingPathComponent(ProfitApp.JsonFileName)
    }
    else {
        return temporaryUrl
    }
}

Here the definitions:
struct ProfitApp {
    static let DocumentDirectoryUrl = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first!)
    static let JsonFileName = "profitdata-2.json"
    static let JsonUrl = ProfitApp.DocumentDirectoryUrl.URLByAppendingPathComponent(ProfitApp.JsonFileName)
}

@katunch Thank you for your help, it's work =)

if I delete oldFile, what happed while sever response with statecoude == 304 ?

authors: cnoon katunch krmao xero88


text:
Add UIButton extension to tvOS target.

This addresses issue https://github.com/Alamofire/AlamofireImage/issues/94

Thanks for this @picciano. I added the UIButton extension and test files to the appropriate tvOS targets in 3ea35180. I also verified that the podspec for tvOS does include the UIButton extension.
I didn't merge your PR directly b/c I'm not sold on the completion change. That is placed where it is because not all the callback logic works if you modify it. I'm also skeptical that it's calling the completion handler twice without being misused. We have a bunch of tests around this behavior already to verify it works properly.
If you're convinced it's calling twice, could you produce a failing test to verify? If you do, I'll be happy to investigate what the issue could be.
Thanks again! 🍻

Thanks.
Regarding the completion call...it's not that it being called twice, it's that it was being called before the self.setImage() call was being made. In general, a completion call should be made last after all work is completed. In our specific case, we are further modifying the image in our completion handler, but since the image was not yet set by the time the completion handler was called, it failed.
Please reconsider the PR. Thanks much.

Thanks for the explanation @picciano.
Unfortunately, it's not as simple as saying the completion closure should only be called after everything is complete. For example, you may be using an ImageTransition over time. When would the completion be called in that case? Also, there are cases where you have already set a different URL for the image view b/c it's in a table view cell being reused. In this case, the image will never be set, but the image is fully downloaded and the image filter is processed and the image is cached. What would the behavior be in this case?
Since the edge cases get fairly complicated here, the completion closure is always called right before the image "would" be set. That does not guarantee however that the image is actually set as mentioned in the cases above.
Regardless of the completion ordering logic, there may be a better way for you to solve your problem. The ImageFilter concept was designed to do exactly what it is "I think" you're trying to accomplish. It sounds like you need to modify the image before it's applied to the image view. Right now you're trying to do that after the image has been set. A better way to do that would be to use an ImageFilter to modify the image asynchronously, then apply the final image to the image view. This is exactly what ImageFilters were designed to do.
Cheers. 🍻

authors: cnoon picciano

repo: Alamofire/AlamofireImage

license: mit


text:
[Feature] Support historical logging for delegated, bonded, and unbonding` mappings.

This PR supports historical logging for the delegated, bonded, and unbonding mappings in credits.aleo.
If the history feature is enabled, the VM will store the above mappings as JSON to a set local directory (the same directory as the .ledger).
This data is stored and updated as follows:

A top-level .history* directory is created at the storage path.
When a block i is added to the ledger, a subdirectory block-<i> is created containing: block-<i>-delegated.json, block-<i>-bonded.json, and block-<i>-unbonding.json.
If the history directory is deleted, it is created once again.
Data is stored as a JSON string for easier consumption. We considered storing it at bytes, but opted for usability over compression.

Pruning and management of the .history directory is left to the node runner.
Note. The entirety of this PR is gated under the history feature.
CI passed mostly here. The failing tests are succeeding locally and unrelated to this PR.

LGTM!
As for CI (thx for pushing this already!): Can you also push a clippy fix? I assume maybe a new Rust version came out. Can you also run the synthesizer tests locally to double check they pass?

Done and the synthesizer tests passed locally.

LGTM. We use a tool that uses a similar mechanism that captures the raw binary values of all mappings and they are quite compact (under 4-16KB per block)

Do you have opinions on whether the data should be stored as raw JSON strings or as bytes?

We ran our own internal CI against this and is passing. Given the fact this is gated behind a CLI flag, I think this is a safe feature to add in here at this point in the development timeline. Thank you @Meshiest and @damons for your review

I just saw this and I'd highly recommend anyone who use this to store the jsons in a fs that supports compression, since with a busy network those data could get huge really fast. Had to manually implement a similar function to debug my explorer before. Also one of the reasons I don't keep a whole history of bonded and deletaged mappings - they are really huge on a live network.

repo: AleoNet/snarkVM


text:
How to use your code to get x,y,w,h of each window

Hi,
Thanks so much for sharing your nice code
I was wondering if I can extract the center of each rectangular and width and height of the rectangular using your code?How to use your code to get x,y,w,h of each window ?
Best regards,
Mohammad

Hi Mohammad,
Thanks for your questions.
For a window defined by x, y, w, h, the center will be (x + w/2, y + h/2).
To get each window as an (x, y, w, h) tuple, I would suggest starting at line 68 in the code and making the following modifications.
windows = {} # Window tuples (x, y, w, h)
wid = 0 # Window ID

for _ in trange(iterations):
        if h > min_height and w > min_width:
            hw, hh = w // 2, h // 2

            # Original Image Integral Image bounding box
            tl = I[y+hh, x+hw] + I[y, x] - I[y, x+hw] - I[y+hh, x]          # Top Left
            tr = I[y+hh, x+w] + I[y, x+hw] - I[y, x+w] - I[y+hh, x+hw]      # Top Right
            bl = I[y+h, x+hw] + I[y+hh, x] - I[y+hh, x+hw] - I[y+h, x]      # Bottom Left
            br = I[y+h, x+w] + I[y+hh, x+hw] - I[y+hh, x+w] - I[y+h, x+hw]  # Bottom Right
            # Squared Grayscale Image Integral Image bounding box
            tls = Isq[y+hh, x+hw] + Isq[y, x] - Isq[y, x+hw] - Isq[y+hh, x]
            trs = Isq[y+hh, x+w] + Isq[y, x+hw] - Isq[y, x+w] - Isq[y+hh, x+hw]
            bls = Isq[y+h, x+hw] + Isq[y+hh, x] - Isq[y+hh, x+hw] - Isq[y+h, x]
            brs = Isq[y+h, x+w] + Isq[y+hh, x+hw] - Isq[y+hh, x+w] - Isq[y+h, x+hw]
            # Grayscale Image Integral Image bounding box
            tlg = Ig[y+hh, x+hw] + Ig[y, x] - Ig[y, x+hw] - Ig[y+hh, x]
            trg = Ig[y+hh, x+w] + Ig[y, x+hw] - Ig[y, x+w] - Ig[y+hh, x+hw]
            blg = Ig[y+h, x+hw] + Ig[y+hh, x] - Ig[y+hh, x+hw] - Ig[y+h, x]
            brg = Ig[y+h, x+w] + Ig[y+hh, x+hw] - Ig[y+hh, x+w] - Ig[y+h, x+hw]

            tlw, tlh = hw, hh
            trw, trh = w - hw, hh
            blw, blh = hw, h - hh
            brw, brh = w - hw, h - hh

            edited[y:y+hh, x:x+hw] = tl / (tlw * tlh)
            edited[y:y+hh, x+hw:x+w] = tr / (trw * trh)
            edited[y+hh:y+h, x:x+hw] = bl / (blw * blh)
            edited[y+hh:y+h, x+hw:x+w] = br / (brw * brh)

            if set_border:
                border(edited[y:y+hh, x:x+hw])
                border(edited[y:y+hh, x+hw:x+w])
                border(edited[y+hh:y+h, x:x+hw])
                border(edited[y+hh:y+h, x+hw:x+w])

            heapq.heappush(quadrants, (-error(tlg, tls, tlw * tlh), x, y, tlw, tlh, wid+0))
            heapq.heappush(quadrants, (-error(trg, trs, trw * trh), x + hw, y, trw, trh, wid+1))
            heapq.heappush(quadrants, (-error(blg, bls, blw * blh), x, y + hh, blw, blh, wid+2))
            heapq.heappush(quadrants, (-error(brg, brs, brw * brh), x + hw, y + hh, brw, brh, wid+3))

            windows[wid+0] = (x, y, tlw, tlh)
            windows[wid+1] = (x + hw, y, trw, trh)
            windows[wid+2] = (x, y + hh, blw, blh)
            windows[wid+3] = (x + hw, y + hh, brw, brh)

            wid += 4

        if quadrants:
            _, x, y, w, h, uid = heapq.heappop(quadrants)
            del windows[uid] # Remove a splitted window
        else:
            break

windows = list(windows.values()) # This will store all windows in the final image as (x, y, w, h) tuples.

Thanks so much for your nice reponse!

authors: AlexEidt mohseniaref

repo: AlexEidt/Quart


text:
Wrong battery capacity

For some reason, waybar is reporting the wrong % remaining on my battery. At the time of writing this, it says 77.33% yet:
~ upower -i /org/freedesktop/UPower/devices/battery_BAT0
  native-path:          BAT0
  vendor:               SMP
  model:                DELL GPM0365
  serial:               437
  power supply:         yes
  updated:              Tue 21 May 2019 18:27:14 BST (31 seconds ago)
  has history:          yes
  has statistics:       yes
  battery
    present:             yes
    rechargeable:        yes
    state:               discharging
    warning-level:       none
    energy:              75.126 Wh
    energy-empty:        0 Wh
    energy-full:         76.9614 Wh
    energy-full-design:  97.0026 Wh
    energy-rate:         12.2664 W
    voltage:             12.587 V
    time to empty:       6.1 hours
    percentage:          97%
    capacity:            79.3395%
    technology:          lithium-ion
    icon-name:          'battery-full-symbolic'
  History (charge):
    1558459634	97.000	discharging
  History (rate):
    1558459634	12.266	discharging

Battery config:
    "battery": {
        "bat": "BAT0",
        "states": {
            // "good": 95,
            "warning": 30,
            "critical": 15
        },
        "format": "{icon} {capacity}%",
        // "format-good": "", // An empty format will hide the module
        "format-full": "Charged  {icon}",
        "format-icons": ["", "", "", "", ""]
    },

What about cat /sys/class/power_supply/BAT0/capacity?

 ~ cat /sys/class/power_supply/BAT0/capacity
78
 ~ upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep percentage
    percentage:          78%

That percentage almost matches though the design capacity of the battery though. Almost:
Waybar reported 66.86%. Upower says:
    energy-full:         76.9614 Wh
    energy-full-design:  97.0026 Wh
    capacity:            79.3395%
    percentage:          83%

So 79.3395% of 83% is 65.851461713

Time to full is also wrong. Waybar says 1h17m, upower says 26m

If waybar report a decimal digit that's because it makes an average of several batteries capacities.
Did you have multiple batteries?

No, just 1 battery:
~ ls --color -la /sys/class/power_supply
total 0
drwxr-xr-x  2 root root 0 May 22 12:46 .
drwxr-xr-x 74 root root 0 May 21 18:31 ..
lrwxrwxrwx  1 root root 0 May 22 12:46 AC -> ../../devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0003:00/power_supply/AC
lrwxrwxrwx  1 root root 0 May 22 12:46 BAT0 -> ../../devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0A:00/power_supply/BAT0

Even waybar can't report a decimal number since capacity is stored in a unsigned int :o

So now my battery is full. Battery capacity ( actual capacity / design capacity) is reported by the system as                79.3395%. Waybar is currently reporting 79.34%. It's a hell of a coincidence though.

It's fixed itself. wtf?
I also had a look at the code for it. I can't explain how it was happening. It's clearly looking at the files I've been catting above.

If you're not able to reproduce it anymore i'll close this issue, is that all right with you?

I'll do it just now. This is very puzzling.

authors: Alexays luispabon

repo: Alexays/Waybar


text:
Support interface (white)list in Network module

I would like to have support for an interface whitelist (which would also work as a hierarchy for preferred interfaces) for the interface option in the Network module.
My use case is that if I switch network connections while I have an active VPN interface (e.g. tun0 from OpenVPN) waybar switches to it and keeps showing it until the corresponding interface gets destroyed or goes down, hiding my "main" interfaces (Wi-Fi and Ethernet). The interface option is not currently useful to avoid this, as it would allow me to chose either the Wi-Fi or the Ethernet interface.
A workaround would be to rename the desided interfaces to have the same prefix, and then use the existing wildcard functionality. However, it's probably not a very good idea to rename a network interface to make it play better with a desktop bar. :)
Would a pull request with this functionality be welcome?

Hi!
For sure go ahead, look at the wildcard functionality, should be the same logic 😄

Proposed solution: reuse the interface option. When it is not present or it is a string, the behaviour is exactly the same as before (we don't want to break existing configs). When it is an array, the following additional logic applies:

checkInterface returns true iff the interface name to be checked is wildcard-matched by at least one string inside the array. I.e. the array serves as a whitelist.
getPreferredIface iterates over all the strings inside the array in order, and attempts to wildcard-match all system interfaces to each. If it finds a matching interface which is not down, then that is the preferred interface; if all matched interfaces are down, the first interface that was matched is the preferred interface; if no interface matched, there is no preferred interface.

This behaviour was chosen to be as consistent as possible with what happens now: when interface matches an interface which is down, that is still the preferred interface. If the wildcard would match multiple interfaces, the first match from getifaddrs() is taken. And when no interface matches, there is no preferred interface. Same as above! :)
It satisfies my use case and hopefully that of other people.
Does that sound ok? May I proceed?

LGTM, you've got my go!

I'm almost done.
There's just one little detail: in network.cpp ev_sock_ is added to various groups to receive notifications. However, nl_recvmsgs_default() is apparently never called.
Which should mean that rtnetlink notifications are not working!
I kinda suspect it was done like this because ev_sock_ is used synchronously in getExternalInterface, and having it also for callbacks meant that getExternalInterface could not read the response to its queries because they were consumed by the callback.
I think the proper fix would be to give getExternalInterface its own socket to do its thing. Does that sound right?

@vmsh0 oh yeah, that was something in my todo list, but I forgot 😢, LGTM, Go on it :)

Ok, it should be fixed, and the new feature seems to work well!
I'm having second thoughts on the fall-back thing. It doesn't really make much sense to fall back to the first matched interface even if it's not running. What would you show it for? And worse, it could confuse the user into thinking that it's actually up. I'm gonna get that out of the way before opening the PR - unless you think it should stay.
A better feature would be a configuration switch which would allow the user to choose how to prioritize interfaces - do they want them prioritized by the order of appearence in the configuration, or do they want to prioritize the whitelisted interface which appears in the system defaut route?
Would you be interested in the feature? Can I go ahead and do that as well?

This behavior should remain the same by default, in case another interface is added later like a vpn, but on the other hand you can make a priority, but only if whitelist is used.

Sorry - I don't think I explained myself very well. Let me try again :)
Existing configs will still behave exactly the same as before. This is imperative! The only thing that will affect existing configs is that the rtnetlink bug is now fixed, so users might see a different update behaviour (using the logic that already existed in network.cpp).
What I'm doubtful about is what the exact behaviour should be when more than one interface is specified in the config file. What is clear is that a list of interfaces should at a minimum always work as a whitelist. I.e. when we have a list of interfaces, no interface that's not in the list can ever be selected by the module. Following that, there needs to be a strategy to select an interface among those specified in the list.
My first idea was to select the first interface that is up (specifically, I'm using the RUNNING flag), and when no interface is up, to just fall back the first (existing) interface in the list, even if it's down. This implied an ordering over the interfaces - specifically, the first interface specified in the list that is up is shown.
However, upon further reflection and tests, I realized that selecting an interface which is not up could easily give the user the illusion that it is up. (E.g. some network drivers and/or userspace tooling don't remove addresses from interfaces when they are brought down). For this reason, I don't really want to push this functionality. It really feels like bad UX.
A simple alternative is just to select the first interface specified in the list that is up. When all interfaces are down, the current if will just be -1, as with the single-interface case. (format-disconnected will be shown on the bar.)
However this is a bit too simple to be useful to most users. So what I wanted to do is to use an enchanced priority algorithm which would prioritize interfaces by the metric of the default routes in which they appear in the routing table (and using the order in the config as a fallback). This would work similarly to the existing auto-selection algorithm (i.e. attempt to show the interface the packets are actually egressing from), but with the whitelist and the fallback to the configuration order. And I was considering the idea of having this enhanced algorithm selectable, i.e. having a config option to enable/disable it.

Oh yeah, great idea, I agree with you, it's better to use only the whitelisted interfaces, so as not to put the user in doubt and the format-disconnected will be used.
If you we're able to implement an algorithm to auto-select the interface by the metric of the default rotues, in terms of UX, it just on the top!
Feel free to refactor some of the Network part to suit your need 😄

Hi! I see you deployed a fix for the update issues. I'll rebase on that. I still have plans to work on the interface list thing & the refactor, I'm just a bit busy with uni right now & it will take some time.
Cheers! :)

how is the state here?

I still use Waybar & still have the issue. I have a partial implementation on my computer, but never gotten around to finishing it. I make no promises, but I will bump it up on my list of priorities :)

authors: Alexays vmsh0 xeruf


text:
feat: extend bluetooth module

Resolves #688
Goal is to show selected bluetooth adapter and its connections. Still a work in progress.
TODO:

[x] adapter information

[x] use config field with name to select an adapter or select one randomly if config field not defined (adapter-alias)
[x] add format replacements for label and tooltip
[x] add new styling classes

[x] connected devices

[x] add format replacement for label for 1 connected device

[x] select either the last connected device for this or from a predefined config option to rank which connected device to display (format-device-preference)

[x] make possible to show information of all connected devices in the tooltip
[x] experimental bluez battery percentage

[x] add format replacement for connected device battery percentage (if available)
[x] show as experimental feature in waybar-bluetooth man page

[x] update the module only when signaled from the bluez D-Bus bus or when the rfkill state has changed (if enabled).
[x] update doc when all features finished
[x] fix style so it matches the project style

I also noticed that there is no entry for the bluetooth module in the wiki. So that should also maybe be added.
Possible future improvements not part of this merge request:

show icon field of the connected bluetooth device when available using a config defined icon theme/size
have format-icons for the connected device battery percentage
change the selected connected device that appears in the main label changeable via scrolling or clicking?? Don't know how that would interact with the current format-device-preferences or show the latest connection model.

Oh cool! I was just about to do this! :)

I think its ready to be reviewed.
This is my first time using meson, so hopefully I didn't make any beginner mistakes there.
Also for the battery percentage feature, I just put it in a seperate experimental section in the waybar-bluetooth man page, since wrapping the code in an experimental build flag would make the code more complicated in my opinion. The code should work in all cases (whether bleuz experimental features are turned on or off and whether a device provides its battery percentage or not). But if it should be wrapped with an experimental build flag, let me know.

Forgot to hide the module when its empty from the linked feature request, so I quickly added it.

LGTM, thx!

authors: Alexays ErikReider daangoossens22


text:
feat(battery): added support for battery state-based classes on the entire waybar

The battery module now applies a single battery state-based class, .battery-<state> on the entire waybar.
This could be useful for, say, changing the bar's background color based on battery level.
config.jsonc:
"battery": {
    "states": {
        "warning": 30,
        "critical": 15
    },
}

style.css:
window#waybar.battery-warning {
  background-color: rgba(247, 218, 68, 0.2);
}

window#waybar.battery-critical {
  background-color: rgba(247, 68, 68, 0.2);
}

I'm sure there are quite a few users who would appreciate this feature: https://www.reddit.com/r/swaywm/comments/kuf9sm/make_waybar_turn_red_as_warning/

LGTM, can you update the man and github wiki to show this new feature? :)

Done! :)

Made some small changes. As of d14a4a2, everything's working as expected.

Thanks!

authors: Alexays ArneshRC


text:
Support multiple contacts for a single project

Context
There is at least one project where we need to list more than one contact person. We do not currently support that.
Problem or idea

contact_email and contact_name will be comma-separated in the project metadata the science team hands off.
The Project model needs to be adjusted accordingly.
The front end should display as many contacts as are associated with the project.

Solution or next step
I'm going to tag @dvenprasad to weigh on the display, specifically. I will also slot this for next sprint.

Add the second one right below the first one as a list
Contact Name1 <contact1@email.com>
Contact Name2 <contact2@email.com>

authors: dvenprasad jaclyn-taroni

repo: AlexsLemonade/scpca-portal


text:
lost connection with Sonoff device and update of SonoffLAN is not possible

I use homeassistand in docker and recently I lost connection with my Sonoff device, though it works in eWelink app.
When I do server check I see error
Component error: sonoff - cannot import name 'ConfigEntryState' from 'homeassistant.config_entries' (/usr/src/homeassistant/homeassistant/config_entries.py)

When I go to HACS I see that SonoffLAN installed version is 2.4.6 and it advices me to update.

But update seems not possible. I tried to update several times and every time after restart I see the same screen that I still running SonoffLAN 2.4.6. Even if I remove SonoffLAN after restart I see that it is installed.
I tried to update to latest HA image, but it doesn't help me.

What is the problem?

About HACS problems you should ask in HACS repo. You always can download new SonoffLAN version manually

This is not about the HACS integrattion, it's about the compatibility with Home Assistant itself.
I was running HA 2021 and started getting this issue, i solved it by upgrading to the latest HA 2023.

authors: AlexxIT marcpaulv schel4ok

repo: AlexxIT/SonoffLAN


text:
Can't setup device error

In v.3.5.4 and core v.2024.1.5 my two L1 led strips are not seen by the integration and I get the following debug:
This error originated from a custom integration.

Logger: custom_components.sonoff.core.ewelink
Source: custom_components/sonoff/core/ewelink/__init__.py:57
Integration: Sonoff (documentation, issues)
First occurred: 8:20:06 AM (4 occurrences)
Last logged: 8:38:59 AM

1000f7d8f7 !! can't setup device
1000ee2049 !! can't setup device
Traceback (most recent call last):
  File "/config/custom_components/sonoff/core/ewelink/__init__.py", line 57, in setup_devices
    entities += [cls(self, device) for cls in get_spec(device)]
                                              ^^^^^^^^^^^^^^^^
  File "/config/custom_components/sonoff/core/devices.py", line 469, in wrapped
    classes = func(device)
              ^^^^^^^^^^^^
  File "/config/custom_components/sonoff/core/devices.py", line 417, in get_spec
    classes = get_custom_spec(classes, device["device_class"])
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/sonoff/core/devices.py", line 437, in get_custom_spec
    classes = [spec(classes[0], base=device_class)] + classes[1:]
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/sonoff/core/devices.py", line 89, in spec
    return type(cls.__name__, DEVICE_CLASS[base], {**bases, **kwargs})
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 408, in __init__
    wrap_attr(cls, property_name)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 380, in wrap_attr
    raise TypeError(f"Can't override {attr_name} in subclass")
TypeError: Can't override _attr_supported_features in subclass

Tried so far 3.5.3 and 3.5.4 will all core versions since 2023.12.4 (last one working fine) but with no luck.
In core v.2023.12.4 I get this device diag:
     "options": {
      "mode": "auto",
      "debug": false
    },
    "errors": [],
    "device": {
      "uiid": 59,
      "params": {
        "bindInfos": "***",
        "version": 8,
        "only_device": {
          "ota": "success"
        },
        "sledOnline": "on",
        "ssid": "***",
        "bssid": "***",
        "switch": "on",
        "light_type": 1,
        "colorR": 127,
        "colorG": 0,
        "colorB": 255,
        "bright": 13,
        "mode": 1,
        "speed": 100,
        "sensitive": 7,
        "rssi": -75,
        "fwVersion": "3.4.3",
        "staMac": "***"
      },
      "model": "L1",
      "online": true,
      "local": null,
      "localtype": null,
      "host": null,
      "deviceid": "1000f7d8f7"
    }
  }
}

Whereas in core v.2024.1.5 the same device diag is:
     "options": {
      "mode": "auto",
      "debug": false
    },
    "errors": [],
    "device": {
      "deviceid": "1000f7d8f7"
    }
  }
}

Any ideas?

I had a similar problem after updating the core and operating system: all (!) SONOFF devices were not recognized. I then also updated the SONOFF LAN in HACS, then rebooted. After that everything works again.

That is not similar to my problem; no restart could save the day. I've tested all core versions after 2024.12.3 (last stable) with the latest SonoffLAN versions (3.5.3 and 3.5.4). Same, reproducible error, yet no feedback.
I will either skip updating the core for ever, or replace the problematic L1s with other led strips.

Please show full device diagnostics

Thanks @AlexxIT. Just updated to core v.2024.1.6 just to get the device diag:

{
"home_assistant": {
"installation_type": "Home Assistant OS",
"version": "2024.1.6",
"dev": false,
"hassio": true,
"virtualenv": false,
"python_version": "3.11.6",
"docker": true,
"arch": "x86_64",
"timezone": "Europe/Athens",
"os_name": "Linux",
"os_version": "6.1.71-haos",
"supervisor": "2024.01.1",
"host_os": "Home Assistant OS 11.4",
"docker_version": "24.0.7",
"chassis": "vm",
"run_as_root": true
},
"custom_components": {
"alexa_media": {
"version": "4.9.0",
"requirements": [
"alexapy==1.27.10",
"packaging>=20.3",
"wrapt>=1.14.0"
]
},
"browser_mod": {
"version": "2.3.0",
"requirements": []
},
"meross_lan": {
"version": "4.5.3",
"requirements": []
},
"sonoff": {
"version": "3.5.4",
"requirements": [
"pycryptodome>=3.6.6"
]
},
"hacs": {
"version": "1.34.0",
"requirements": [
"aiogithubapi>=22.10.1"
]
},
"localtuya": {
"version": "5.2.1",
"requirements": []
}
},
"integration_manifest": {
"domain": "sonoff",
"name": "Sonoff",
"codeowners": [
"@AlexxIT"
],
"config_flow": true,
"dependencies": [
"http",
"zeroconf"
],
"documentation": "https://github.com/AlexxIT/SonoffLAN",
"iot_class": "local_push",
"issue_tracker": "https://github.com/AlexxIT/SonoffLAN/issues",
"requirements": [
"pycryptodome>=3.6.6"
],
"version": "3.5.4",
"is_built_in": false
},
"data": {
"version": "a4a8c5f",
"cloud_auth": true,
"config": {
"username": "",
"password": "",
"force_update": [
"temperature",
"power"
],
"scan_interval": "00:05:00",
"devices": {
"1000ac3f02": {
"device_class": "light",
"name": "Shelf lights"
},
"1000a5462c": {
"device_class": "light",
"name": "Kitchen lights"
},
"1000b6cf8a": {
"device_class": "light",
"name": "Back bedroom lights"
},
"1000940497": {
"device_class": "light",
"name": "Entrance light"
},
"1000c9efc5": {
"device_class": "light",
"name": "Porch light"
},
"1000a4b634": {
"device_class": "light",
"name": "Lamp"
},
"100099b647": {
"device_class": "light",
"name": "Light"
},
"1000b691fa": {
"device_class": "light",
"name": "Main bedroom lights"
},
"1000ca0133": {
"device_class": "light",
"name": "Cloud light"
},
"1000dd1176": {
"device_class": "light",
"name": "Front bedroom lights"
},
"1000ee2049": {
"device_class": "light",
"name": "Back bedroom led strip"
},
"1000f7d8f7": {
"device_class": "light",
"name": "Front bedroom led strip"
},
"1000900866": {
"device_class": "light",
"name": "Hassio"
}
},
"rfbridge": {
"Door": {
"device_class": "door",
"timeout": 10
},
"Button A": {
"device_class": "motion",
"timeout": 10
},
"Button B": {
"device_class": "motion",
"timeout": 10
},
"BridgeMotionSensor1": {
"device_class": "motion",
"timeout": 10
},
"PIR3-RF1": {
"device_class": "motion",
"timeout": 6
}
}
},
"options": {
"mode": "auto",
"debug": false
},
"errors": [],
"device": {
"deviceid": "1000f7d8f7"
}
}
}

One of the two (L1) devices having the issues is "deviceid": "1000f7d8f7"
In the Settings/System/Logs is get the following:

2024-02-06 11:21:48.373 WARNING (MainThread) [custom_components.sonoff.core.ewelink] 1000f7d8f7 !! can't setup device
Traceback (most recent call last):
File "/config/custom_components/sonoff/core/ewelink/init.py", line 57, in setup_devices
entities += [cls(self, device) for cls in get_spec(device)]
^^^^^^^^^^^^^^^^
File "/config/custom_components/sonoff/core/devices.py", line 469, in wrapped
classes = func(device)
^^^^^^^^^^^^
File "/config/custom_components/sonoff/core/devices.py", line 417, in get_spec
classes = get_custom_spec(classes, device["device_class"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/sonoff/core/devices.py", line 437, in get_custom_spec
classes = [spec(classes[0], base=device_class)] + classes[1:]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/sonoff/core/devices.py", line 89, in spec
return type(cls.name, DEVICE_CLASS[base], {**bases, **kwargs})
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 408, in init
wrap_attr(cls, property_name)
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 380, in wrap_attr
raise TypeError(f"Can't override {attr_name} in subclass")
TypeError: Can't override _attr_supported_features in subclass

The device remains unresponsive through the HA, however, it is fully functional in eWelink:

Finally. You should have done this a month ago :)
Problem with "device_class": "light" in your YAML. You don't need this for L1, because it is light by default.
Anyway it is bug and should be fixed.

Now that you mention there are still some left overs in my yaml config file from the era (can't remember when exactly) when we manually added the sonoff: integration details.
It seems that I still have:

ewelink integration

sonoff:
username: ''
password: ''
devices:
1000f7d8f7: blablabla
etc...
Shall I remove them all?
Thanks for pointing to the problem!

It's up to you to decide what you need.
https://github.com/AlexxIT/SonoffLAN#configuration-yaml

Yeap you are right. I still had few lines in my config yaml to overwrite the class of some devices (those ran by sonoff mini mostly).
Now everything is back to normal.
Thanks for the support.

Thank you for posting error. Most users stop at "nothing works for me after update".

https://github.com/AlexxIT/SonoffLAN/releases/tag/v3.6.0

authors: AK-github888 AlexxIT Kydonakis


text:
Create zh-Hant.json

Add Taiwanese translation

Thanks!

authors: AlexxIT xangin


text:
Refreshing the poster on a specified interval

In my setup, I'm trying to set up WebRTC like my Generic Cameras where the static image from the camera is pulled in on a regular basis and displayed on screen, and I can tap the mode or source labels to view the video on-demand.
While I have the video-on-demand part down, when on the poster view, the image doesn't update on a regular basis. I need to refresh the entire screen for the image to load.
I've scoured the docs to find a command that'll refresh the poster image on a regular basis, but I cannot find it.
Below is my setup for reference... could anyone tell me if this is possible with WebRTC, or has this issue become a feature request?
type: custom:webrtc-camera
poster: http://10.8.0.9:5000/snapshot/west-side-front.jpg
streams:
  - url: ''
  - url: rtsp://03cabcc9-ring-mqtt:8554/9c76138a550e_live
ui: true

Did you ever get this working? I'm trying to accomplish the same, and hopefully also adding the ability to just tap anywhere on the card to display it as a pop-up card the way the picture entity card normally would (and, ideally switch from the poster image to the HD stream).
I'm going to keep playing with this to see if I can figure it out.  If i do, i'll post back here.

我也需要這個功能，但只要截圖URL一樣，卡片就不會更新靜態圖片

authors: daytonturner exee25 infectedroot

repo: AlexxIT/WebRTC