Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow arbitrary content in music box messages #12271

Merged
merged 8 commits into from
Jan 24, 2024

Conversation

SuperJMN
Copy link
Collaborator

@SuperJMN SuperJMN commented Jan 17, 2024

This allows any content where we previously had non-formatted text. It allows more visual hints in the MusicBox and could be used in other parts of the application.

Example: image

Fixes #11567

@SuperJMN SuperJMN self-assigned this Jan 17, 2024
Copy link
Collaborator

@yahiheb yahiheb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK

Copy link
Collaborator

@MarnixCroes MarnixCroes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tack c62de8b

maybe add a tooltip (Play) to the icon?
I know it seems obvious, but most apps (youtube etc) have tooltips even for a Play button.

@@ -28,7 +29,7 @@ public partial class CoinJoinStateViewModel : ViewModelBase
private const string WaitingForBlameRoundMessage = "Awaiting the blame round";
private const string WaitingRoundMessage = "Awaiting a round";
private const string PlebStopMessage = "Coinjoin may be uneconomical";
private const string PlebStopMessageBelow = "Add more funds or press 'Play' to bypass";
public const string PlebStopMessageBelow = "Add more funds or press 'Play' to bypass";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ultra nit: to have the same with line 23
maybe change if you retouch, or feel free to ignore

Suggested change
public const string PlebStopMessageBelow = "Add more funds or press 'Play' to bypass";
public const string PlebStopMessageBelow = "Add more funds or press Play to bypass";

yahiheb
yahiheb previously approved these changes Jan 18, 2024
Copy link
Collaborator

@yahiheb yahiheb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK

Comment on lines 15 to 37
<converters:KeyToDictionaryItemConverter x:Key="MusicBoxMessageConverter">
<ResourceDictionary>
<StackPanel x:Key="{x:Static wallets:CoinJoinStateViewModel.PressPlayToStartMessage}">
<TextBlock Inlines="">
<Run>Press </Run>
<InlineUIContainer>
<PathIcon Data="{StaticResource play_regular}" />
</InlineUIContainer>
<Run> to start</Run>
</TextBlock>
</StackPanel>
<StackPanel x:Key="{x:Static wallets:CoinJoinStateViewModel.PlebStopMessageBelow}">
<TextBlock Inlines="">
<Run>Add more funds or press </Run>
<InlineUIContainer>
<PathIcon Data="{StaticResource play_regular}" />
</InlineUIContainer>
<Run> to bypass</Run>
</TextBlock>
</StackPanel>
</ResourceDictionary>
</converters:KeyToDictionaryItemConverter>
</UserControl.Resources>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part bothers me, as the message is duplicated or at least the one in the ViewModel is useless...

What do you think about having a converter that generates Content from String?

For example, the string Press Play to start string is bound to the ContentControl in XAML, with a converter.
The convert in this case would start to build the content programmatically.

Basically split the string by space, so we have a list of words, then just iterate through them.

// Create a TextBlock
// Init the inlines

if (word == "Play")
   // add the Play icon to TextBlock.Inlines
else
  // add a TextBlock with the word to TextBlock.Inlines
  
Return TextBlock;

With we would be more flexible, the messages won't be duplicated plus we can change the messages more easily and dynamically.
Also, we could do the same for Stop or Pause icon.

WDYT?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I like your approach. I've already implemented it. Please tell me if it's as you expected.

Copy link
Collaborator

@MarnixCroes MarnixCroes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4a31a35, this crashes when pressing pause
press play -> press stop -> crash

Exception type: System.InvalidOperationException

Message: The control already has a visual parent.

Stack Trace:    at Avalonia.Visual.ValidateVisualChild(Visual c)
   at Avalonia.Collections.AvaloniaList`1.Add(T item)
   at Avalonia.Controls.TextBlock.MeasureOverride(Size availableSize)
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize)
   at Avalonia.Layout.Layoutable.Measure(Size availableSize)
   at Avalonia.Layout.LayoutHelper.MeasureChild(Layoutable control, Size availableSize, Thickness padding, Thickness borderThickness)
   at Avalonia.Controls.Presenters.ContentPresenter.MeasureOverride(Size availableSize)
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize)
   at Avalonia.Layout.Layoutable.Measure(Size availableSize)
   at Avalonia.Layout.LayoutManager.Measure(Layoutable control)
   at Avalonia.Layout.LayoutManager.ExecuteMeasurePass()
   at Avalonia.Layout.LayoutManager.InnerLayoutPass()
   at Avalonia.Layout.LayoutManager.ExecuteLayoutPass()
   at Avalonia.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at Avalonia.Media.MediaContext.RenderCore()
   at Avalonia.Media.MediaContext.Render()
   at Avalonia.Threading.DispatcherOperation.InvokeCore()
   at Avalonia.Threading.DispatcherOperation.Execute()
   at Avalonia.Threading.Dispatcher.ExecuteJob(DispatcherOperation job)
   at Avalonia.Threading.Dispatcher.ExecuteJobsCore(Boolean fromExplicitBackgroundProcessingCallback)
   at Avalonia.Threading.Dispatcher.Signaled()
   at Avalonia.X11.X11PlatformThreading.CheckSignaled()
   at Avalonia.X11.X11PlatformThreading.RunLoop(CancellationToken cancellationToken)
   at Avalonia.Threading.DispatcherFrame.Run(IControlledDispatcherImpl impl)
   at Avalonia.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken cancellationToken)
   at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args)
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(AppBuilder builder, String[] args, ShutdownMode shutdownMode)
   at WalletWasabi.Fluent.Desktop.WasabiAppExtensions.<>c__DisplayClass0_0.<RunAsGuiAsync>b__0() in WalletWasabi.Fluent.Desktop/Program.cs:line 190
   at WalletWasabi.Daemon.WasabiApplication.RunAsync(Func`1 afterStarting) in WalletWasabi.Daemon/WasabiAppBuilder.cs:line 78
   at WalletWasabi.Fluent.Desktop.WasabiAppExtensions.RunAsGuiAsync(WasabiApplication app) in WalletWasabi.Fluent.Desktop/Program.cs:line 147
   at WalletWasabi.Fluent.Desktop.Program.Main(String[] args) in WalletWasabi.Fluent.Desktop/Program.cs:line 63

Inner Exception: 

@pull-request-size pull-request-size bot added size/M and removed size/L labels Jan 24, 2024
@SuperJMN
Copy link
Collaborator Author

4a31a35, this crashes when pressing pause press play -> press stop -> crash

Exception type: System.InvalidOperationException

Message: The control already has a visual parent.

Stack Trace:    at Avalonia.Visual.ValidateVisualChild(Visual c)
   at Avalonia.Collections.AvaloniaList`1.Add(T item)
   at Avalonia.Controls.TextBlock.MeasureOverride(Size availableSize)
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize)
   at Avalonia.Layout.Layoutable.Measure(Size availableSize)
   at Avalonia.Layout.LayoutHelper.MeasureChild(Layoutable control, Size availableSize, Thickness padding, Thickness borderThickness)
   at Avalonia.Controls.Presenters.ContentPresenter.MeasureOverride(Size availableSize)
   at Avalonia.Layout.Layoutable.MeasureCore(Size availableSize)
   at Avalonia.Layout.Layoutable.Measure(Size availableSize)
   at Avalonia.Layout.LayoutManager.Measure(Layoutable control)
   at Avalonia.Layout.LayoutManager.ExecuteMeasurePass()
   at Avalonia.Layout.LayoutManager.InnerLayoutPass()
   at Avalonia.Layout.LayoutManager.ExecuteLayoutPass()
   at Avalonia.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at Avalonia.Media.MediaContext.RenderCore()
   at Avalonia.Media.MediaContext.Render()
   at Avalonia.Threading.DispatcherOperation.InvokeCore()
   at Avalonia.Threading.DispatcherOperation.Execute()
   at Avalonia.Threading.Dispatcher.ExecuteJob(DispatcherOperation job)
   at Avalonia.Threading.Dispatcher.ExecuteJobsCore(Boolean fromExplicitBackgroundProcessingCallback)
   at Avalonia.Threading.Dispatcher.Signaled()
   at Avalonia.X11.X11PlatformThreading.CheckSignaled()
   at Avalonia.X11.X11PlatformThreading.RunLoop(CancellationToken cancellationToken)
   at Avalonia.Threading.DispatcherFrame.Run(IControlledDispatcherImpl impl)
   at Avalonia.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken cancellationToken)
   at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args)
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(AppBuilder builder, String[] args, ShutdownMode shutdownMode)
   at WalletWasabi.Fluent.Desktop.WasabiAppExtensions.<>c__DisplayClass0_0.<RunAsGuiAsync>b__0() in WalletWasabi.Fluent.Desktop/Program.cs:line 190
   at WalletWasabi.Daemon.WasabiApplication.RunAsync(Func`1 afterStarting) in WalletWasabi.Daemon/WasabiAppBuilder.cs:line 78
   at WalletWasabi.Fluent.Desktop.WasabiAppExtensions.RunAsGuiAsync(WasabiApplication app) in WalletWasabi.Fluent.Desktop/Program.cs:line 147
   at WalletWasabi.Fluent.Desktop.Program.Main(String[] args) in WalletWasabi.Fluent.Desktop/Program.cs:line 63

Inner Exception: 

Oh yeah, I discovered the problem. It seems that x:Shared="False" still doesn't work in Avalonia UI. I had to take an alternate aproach. It works now.

Thanks for reporting!

Copy link
Collaborator

@MarnixCroes MarnixCroes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f74345a works

imo having tooltip for play, pause and stop in the musicbox is good to add.
can be for a follow-up

WalletWasabi.Fluent/Views/Wallets/MusicControlsView.axaml Outdated Show resolved Hide resolved
@pull-request-size pull-request-size bot added size/L and removed size/M labels Jan 24, 2024
@pull-request-size pull-request-size bot added size/M and removed size/L labels Jan 24, 2024
Copy link
Collaborator

@soosr soosr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK

@soosr soosr merged commit f0b9fd7 into WalletWasabi:master Jan 24, 2024
3 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[UX] Use play/pause/stop icons instead of words with the musicbox messages
4 participants