{"action":"created","issue":{"url":"https://api.github.com/repos/reactiveui/ReactiveUI/issues/1055","labels_url":"https://api.github.com/repos/reactiveui/ReactiveUI/issues/1055/labels{/name}","comments_url":"https://api.github.com/repos/reactiveui/ReactiveUI/issues/1055/comments","events_url":"https://api.github.com/repos/reactiveui/ReactiveUI/issues/1055/events","html_url":"https://github.com/reactiveui/ReactiveUI/pull/1055","id":128505385,"number":1055,"title":"Improve interactions implementation","user":{"login":"kentcb","id":1901832,"avatar_url":"https://avatars.githubusercontent.com/u/1901832?v=3","gravatar_id":"","url":"https://api.github.com/users/kentcb","html_url":"https://github.com/kentcb","followers_url":"https://api.github.com/users/kentcb/followers","following_url":"https://api.github.com/users/kentcb/following{/other_user}","gists_url":"https://api.github.com/users/kentcb/gists{/gist_id}","starred_url":"https://api.github.com/users/kentcb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kentcb/subscriptions","organizations_url":"https://api.github.com/users/kentcb/orgs","repos_url":"https://api.github.com/users/kentcb/repos","events_url":"https://api.github.com/users/kentcb/events{/privacy}","received_events_url":"https://api.github.com/users/kentcb/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/reactiveui/ReactiveUI/labels/enhancement","name":"enhancement","color":"207de5"},{"url":"https://api.github.com/repos/reactiveui/ReactiveUI/labels/rxui","name":"rxui","color":"fef2c0"}],"state":"open","locked":false,"assignee":{"login":"kentcb","id":1901832,"avatar_url":"https://avatars.githubusercontent.com/u/1901832?v=3","gravatar_id":"","url":"https://api.github.com/users/kentcb","html_url":"https://github.com/kentcb","followers_url":"https://api.github.com/users/kentcb/followers","following_url":"https://api.github.com/users/kentcb/following{/other_user}","gists_url":"https://api.github.com/users/kentcb/gists{/gist_id}","starred_url":"https://api.github.com/users/kentcb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kentcb/subscriptions","organizations_url":"https://api.github.com/users/kentcb/orgs","repos_url":"https://api.github.com/users/kentcb/repos","events_url":"https://api.github.com/users/kentcb/events{/privacy}","received_events_url":"https://api.github.com/users/kentcb/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/reactiveui/ReactiveUI/milestones/2","html_url":"https://github.com/reactiveui/ReactiveUI/milestones/ReactiveUI%207.0","labels_url":"https://api.github.com/repos/reactiveui/ReactiveUI/milestones/2/labels","id":1469357,"number":2,"title":"ReactiveUI 7.0","description":null,"creator":{"login":"ghuntley","id":127353,"avatar_url":"https://avatars.githubusercontent.com/u/127353?v=3","gravatar_id":"","url":"https://api.github.com/users/ghuntley","html_url":"https://github.com/ghuntley","followers_url":"https://api.github.com/users/ghuntley/followers","following_url":"https://api.github.com/users/ghuntley/following{/other_user}","gists_url":"https://api.github.com/users/ghuntley/gists{/gist_id}","starred_url":"https://api.github.com/users/ghuntley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ghuntley/subscriptions","organizations_url":"https://api.github.com/users/ghuntley/orgs","repos_url":"https://api.github.com/users/ghuntley/repos","events_url":"https://api.github.com/users/ghuntley/events{/privacy}","received_events_url":"https://api.github.com/users/ghuntley/received_events","type":"User","site_admin":false},"open_issues":14,"closed_issues":21,"state":"open","created_at":"2015-12-21T10:54:22Z","updated_at":"2016-01-25T10:27:47Z","due_on":null,"closed_at":null},"comments":8,"created_at":"2016-01-25T10:27:47Z","updated_at":"2016-01-25T23:31:29Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/reactiveui/ReactiveUI/pulls/1055","html_url":"https://github.com/reactiveui/ReactiveUI/pull/1055","diff_url":"https://github.com/reactiveui/ReactiveUI/pull/1055.diff","patch_url":"https://github.com/reactiveui/ReactiveUI/pull/1055.patch"},"body":"This PR improves the interactions implementation by:\r\n\r\n* generalizing the name to \"interactions\" rather than \"user interactions\"\r\n* splitting the responsibility for the distribution of interactions into a separate, non-static, class\r\n* lots of smaller improvements to round edges in the API\r\n\r\nSee the documentation for this feature [here](http://docs.reactiveui.net/en/user-guide/interactions/index.html).\r\n\r\nTODO:\r\n- [ ] Decide on naming"},"comment":{"url":"https://api.github.com/repos/reactiveui/ReactiveUI/issues/comments/174729447","html_url":"https://github.com/reactiveui/ReactiveUI/pull/1055#issuecomment-174729447","issue_url":"https://api.github.com/repos/reactiveui/ReactiveUI/issues/1055","id":174729447,"user":{"login":"kentcb","id":1901832,"avatar_url":"https://avatars.githubusercontent.com/u/1901832?v=3","gravatar_id":"","url":"https://api.github.com/users/kentcb","html_url":"https://github.com/kentcb","followers_url":"https://api.github.com/users/kentcb/followers","following_url":"https://api.github.com/users/kentcb/following{/other_user}","gists_url":"https://api.github.com/users/kentcb/gists{/gist_id}","starred_url":"https://api.github.com/users/kentcb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kentcb/subscriptions","organizations_url":"https://api.github.com/users/kentcb/orgs","repos_url":"https://api.github.com/users/kentcb/repos","events_url":"https://api.github.com/users/kentcb/events{/privacy}","received_events_url":"https://api.github.com/users/kentcb/received_events","type":"User","site_admin":false},"created_at":"2016-01-25T23:31:29Z","updated_at":"2016-01-25T23:31:29Z","body":"@mteper Thanks for the suggestion. I like the idea of formalizing the input and output (though I prefer request/response terminology). I'm not a huge fan of forcing handlers to return something. This, in particular, makes no sense to me:\r\n\r\n```cs\r\ncontext.SetResult(fileInfo, handled: false);\r\n```\r\n\r\nSetting a result _is_ handling the interaction, so this is a contradictory API. However, I noticed you introduced another concept in your most recent post: the context. To me, it would make sense for the context to include a `Request` property and a `SetResponse` method. If handlers don't want to handle the interaction, they simply don't call the `SetResponse` method. Is this what you intended to convey? If so, I believe this means we'd have:\r\n\r\n```\r\nInteraction<TRequest, TResponse>\r\n + RegisterHandler(Func<InteractionContext<TRequest, TResponse>, IObservable<Unit>>) // plus other overloads\r\n + Handle(TRequest input) : IObservable<TResponse>\r\n\r\nInteractionContext<TRequest, TResponse>\r\n+ IsHandled : bool\r\n+ Request : TRequest (get)\r\n+ SetResponse(TResponse)\r\n+ GetResponse() : TResponse\r\n\r\nUnhandledInteractionException<TRequest, TResponse>\r\n+ Interaction : Interaction<TRequest, TResponse>\r\n+ Request : TRequest\r\n```\r\n\r\nAnd usage would resemble:\r\n\r\n```cs\r\n// view model\r\nprivate readonly Interaction<string, bool> confirmDelete = new Interaction<string, bool>();\r\n\r\npublic Interaction<string, bool> ConfirmDelete => this.confirmDelete;\r\n\r\nprivate async Task DeleteFileAsync()\r\n{\r\n    var fileName = ...;\r\n\r\n    // this will throw if nothing handles the interaction\r\n    var confirm = await this.confirmDelete.Handle(fileName);\r\n\r\n    if (confirm)\r\n    {\r\n        // delete the file\r\n    }\r\n}\r\n\r\n// view\r\nthis\r\n    .ViewModel\r\n    .ConfirmDelete\r\n    .RegisterHandler(\r\n        async context =>\r\n        {\r\n            var result = await this.DisplayMessageAsync(\"Confirm Delete\", $\"Delete file '{context.Request}'?\", \"YES\", \"NO\");\r\n\r\n            // handler could simply not make this call if it does not wish to handle the interaction\r\n            context.SetResponse(result);\r\n        });\r\n```\r\n\r\nDoes this sound good to you?"}}