Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
XmppContact.cs
1using System;
2using System.Text;
3using System.Threading.Tasks;
4using System.Xml;
5using System.Windows;
6using System.Windows.Controls;
7using System.Windows.Input;
8using System.Windows.Media;
9using System.Windows.Media.Imaging;
17
19{
23 public class XmppContact : XmppNode
24 {
25 private readonly XmppClient client;
26 private readonly string bareJid;
27 private readonly bool supportsRdp;
28
29 public XmppContact(TreeNode Parent, XmppClient Client, string BareJid, bool SupportsRdp)
30 : base(Parent)
31 {
32 this.client = Client;
33 this.bareJid = BareJid;
34 this.supportsRdp = SupportsRdp;
35 }
36
37 public override string Header => this.bareJid;
38
39 public override string TypeName
40 {
41 get { return "Unknown"; }
42 }
43
44 public string BareJID => this.bareJid;
45
46 public override string FullJID
47 {
48 get
49 {
50 RosterItem Item = this.client[this.bareJid];
51 if (Item is null || !Item.HasLastPresence)
52 return this.bareJid;
53 else
54 return Item.LastPresenceFullJid;
55 }
56 }
57
59 {
60 get
61 {
62 return this.client[this.bareJid];
63 }
64
65 internal set
66 {
67 RosterItem Item = this.client[this.bareJid];
68 if (Item != value)
69 this.client[this.bareJid] = value;
70 }
71 }
72
73 public override void Write(XmlWriter Output)
74 {
75 // Don't output.
76 }
77
79 {
80 get
81 {
82 XmppAccountNode AccountNode = this.XmppAccountNode;
83 if (AccountNode is null || !AccountNode.IsOnline)
84 return Availability.Offline;
85
86 RosterItem Item = this.client[this.bareJid];
88
89 if (e is null)
90 return Availability.Offline;
91 else
92 return e.Availability;
93 }
94 }
95
97 {
98 get
99 {
100 XmppAccountNode AccountNode = this.XmppAccountNode;
101 if (AccountNode is null || !AccountNode.IsOnline)
102 return SubscriptionState.Unknown;
103
104 RosterItem Item = this.client[this.bareJid];
105 if (Item is null)
106 return SubscriptionState.Unknown;
107 else
108 return Item.State;
109 }
110 }
111
112 public override ImageSource ImageResource
113 {
114 get
115 {
116 switch (this.Availability)
117 {
118 case Availability.Away:
119 return XmppAccountNode.away;
120
121 case Availability.Chat:
122 return XmppAccountNode.chat;
123
124 case Availability.DoNotDisturb:
125 return XmppAccountNode.busy;
126
127 case Availability.ExtendedAway:
128 return XmppAccountNode.extendedAway;
129
130 case Availability.Online:
131 return XmppAccountNode.online;
132
133 case Availability.Offline:
134 default:
135 return XmppAccountNode.offline;
136 }
137 }
138 }
139
140 public override ImageSource ImageResource2
141 {
142 get
143 {
144 switch (this.SubscriptionState)
145 {
146 case SubscriptionState.None:
147 return XmppAccountNode.none;
148
149 case SubscriptionState.From:
150 return XmppAccountNode.from;
151
152 case SubscriptionState.To:
153 return XmppAccountNode.to;
154
155 case SubscriptionState.Both:
156 return XmppAccountNode.both;
157
158 case SubscriptionState.Unknown:
159 default:
160 return null;
161 }
162 }
163 }
164
165 public override Visibility ImageResource2Visibility
166 {
167 get
168 {
169 switch (this.SubscriptionState)
170 {
171 case SubscriptionState.None:
172 case SubscriptionState.From:
173 case SubscriptionState.To:
174 case SubscriptionState.Both:
175 return Visibility.Visible;
176
177 case SubscriptionState.Unknown:
178 default:
179 return Visibility.Hidden;
180 }
181 }
182 }
183
184 public override string ToolTip
185 {
186 get
187 {
188 XmppAccountNode AccountNode = this.XmppAccountNode;
189 if (AccountNode is null)
190 return string.Empty;
191 else if (!AccountNode.IsOnline)
192 return AccountNode.BareJID + " is not connected.";
193
195
196 if (e is null)
197 return "Status unknown. No presence received.";
198 else
199 {
200 switch (e.Availability)
201 {
202 case Availability.Away:
203 return "Contact is away.";
204
205 case Availability.Chat:
206 return "Contact is ready to chat.";
207
208 case Availability.DoNotDisturb:
209 return "Contact is busy and doesn't want to be disturbed.";
210
211 case Availability.ExtendedAway:
212 return "Contact is away for an extended period.";
213
214 case Availability.Online:
215 return "Contact is online.";
216
217 case Availability.Offline:
218 default:
219 return "Contact is offline.";
220 }
221 }
222 }
223 }
224
225 public override bool CanAddChildren
226 {
227 get { return false; }
228 }
229
230 public override bool CanDelete
231 {
232 get { return true; }
233 }
234
235 public override bool CanEdit
236 {
237 get { return false; } // TODO: Edit Friendly name, groups
238 }
239
240 public override bool CanRecycle
241 {
242 get { return false; }
243 }
244
245 public override string Key => this.bareJid;
246
247 public override bool CanChat
248 {
249 get
250 {
251 Availability Availability = this.Availability;
252
253 return Availability != Availability.DoNotDisturb;
254 }
255 }
256
257 public XmppAccountNode XmppAccountNode
258 {
259 get
260 {
261 TreeNode Loop = this.Parent;
262 XmppAccountNode Result = Loop as XmppAccountNode;
263
264 while (Result is null && !(Loop is null))
265 {
266 Loop = Loop.Parent;
267 Result = Loop as XmppAccountNode;
268 }
269
270 return Result;
271 }
272 }
273
274 public override async Task SendChatMessage(string Message, string ThreadId, MarkdownDocument Markdown)
275 {
276 XmppAccountNode XmppAccountNode = this.XmppAccountNode;
277 if (!(XmppAccountNode is null))
278 {
279 string To = this.RosterItem?.LastPresenceFullJid;
280 if (string.IsNullOrEmpty(To))
281 To = this.bareJid;
282
283 if (Markdown is null)
284 await XmppAccountNode.Client.SendChatMessage(To, Message, string.Empty, string.Empty, ThreadId);
285 else
286 {
287 await XmppAccountNode.Client.SendMessage(QoSLevel.Unacknowledged, MessageType.Chat, To,
288 await MultiFormatMessage(Message, Markdown), string.Empty, string.Empty, string.Empty, ThreadId, string.Empty, null, null);
289 }
290 }
291 }
292
293 public static async Task<string> MultiFormatMessage(string PlainText, MarkdownDocument Markdown)
294 {
295 if (PlainText is null)
296 PlainText = (await Markdown.GeneratePlainText()).Trim();
297
298 string HTML = HtmlDocument.GetBody(await Markdown.GenerateHTML()).Trim();
299 StringBuilder sb = new StringBuilder();
300
301 sb.Append("<body>");
302 sb.Append(XML.Encode(PlainText));
303 sb.Append("</body>");
304 sb.Append("<html xmlns='http://jabber.org/protocol/xhtml-im'>");
305 sb.Append("<body xmlns='http://www.w3.org/1999/xhtml'>");
306 sb.Append(HTML);
307 sb.Append("</body></html>");
308 sb.Append("<content xmlns='urn:xmpp:content' type='text/markdown'>");
309 sb.Append(XML.HtmlValueEncode(await Markdown.GenerateMarkdown()));
310 sb.Append("</content>");
311
312 return sb.ToString();
313 }
314
315 public override void AddContexMenuItems(ref string CurrentGroup, ContextMenu Menu)
316 {
317 base.AddContexMenuItems(ref CurrentGroup, Menu);
318
319 XmppAccountNode XmppAccountNode = this.XmppAccountNode;
320
321 if (!(XmppAccountNode is null) && XmppAccountNode.IsOnline)
322 {
323 SubscriptionState SubscriptionState = this.SubscriptionState;
324 MenuItem MenuItem;
325 string s;
326
328 {
329 this.GroupSeparator(ref CurrentGroup, "Subscriptions", Menu);
330
332 s = "../Graphics/To.png";
333 else
334 s = "../Graphics/Both.png";
335
336 Menu.Items.Add(MenuItem = new MenuItem()
337 {
338 Header = "_Subscribe to",
339 IsEnabled = true,
340 Icon = new Image()
341 {
342 Source = new BitmapImage(new Uri(s, UriKind.Relative)),
343 Width = 16,
344 Height = 16
345 }
346 });
347
348 MenuItem.Click += this.Subscribe_Click;
349 }
350
352 {
353 this.GroupSeparator(ref CurrentGroup, "Subscriptions", Menu);
354
356 s = "../Graphics/None.png";
357 else
358 s = "../Graphics/From.png";
359
360 Menu.Items.Add(MenuItem = new MenuItem()
361 {
362 Header = "_Unsubscribe from",
363 IsEnabled = true,
364 Icon = new Image()
365 {
366 Source = new BitmapImage(new Uri(s, UriKind.Relative)),
367 Width = 16,
368 Height = 16
369 }
370 });
371
372 MenuItem.Click += this.Unsubscribe_Click;
373 }
374
375 }
376 }
377
378 private void Subscribe_Click(object Sender, RoutedEventArgs e)
379 {
380 this.XmppAccountNode?.Client?.RequestPresenceSubscription(this.bareJid);
381 }
382
383 private void Unsubscribe_Click(object Sender, RoutedEventArgs e)
384 {
385 this.XmppAccountNode?.Client?.RequestPresenceUnsubscription(this.bareJid);
386 }
387
388 public override bool CanConfigure => this.supportsRdp && !string.IsNullOrEmpty(this.LastOnlineFullJid);
389
390 private string LastOnlineFullJid
391 {
392 get
393 {
394 try
395 {
396 if (this.client is null)
397 return null;
398
399 RosterItem Item = this.client[this.bareJid];
400 if (Item is null)
401 return null;
402
404 if (e?.IsOnline ?? false)
405 return e.From;
406 else
407 return null;
408 }
409 catch (Exception)
410 {
411 return null;
412 }
413 }
414 }
415
419 protected virtual bool UseActuatorControl => false;
420
421 public override async void Configure()
422 {
423 if (this.UseActuatorControl)
424 {
425 base.Configure();
426 return;
427 }
428
429 string FullJid = this.LastOnlineFullJid;
430 if (string.IsNullOrEmpty(FullJid))
431 return;
432
433 RemoteDesktopClient RdpClient = this.XmppAccountNode.RdpClient;
434 if (RdpClient is null)
435 return;
436
437 XmppClient Client = this.client;
438 bool DisposeRdpClient = false;
439
440 try
441 {
442 Mouse.OverrideCursor = Cursors.Wait;
443
444 Guid SessionGuid = Guid.NewGuid();
445 RemoteDesktopView View = new RemoteDesktopView(this, Client, RdpClient, DisposeRdpClient);
446
447 this.XmppAccountNode.ReregisterView(SessionGuid.ToString(), View);
448
449 View.Session = await RdpClient.StartSessionAsync(FullJid, SessionGuid);
450
451 Mouse.OverrideCursor = null;
452
453 TabItem TabItem = MainWindow.NewTab(this.bareJid);
454 MainWindow.currentInstance.Tabs.Items.Add(TabItem);
455
456 TabItem.Content = View;
457
458 MainWindow.currentInstance.Tabs.SelectedItem = TabItem;
459 }
460 catch (Exception ex)
461 {
462 if (DisposeRdpClient)
463 RdpClient.Dispose();
464
465 MainWindow.ErrorBox(ex.Message);
466 }
467 }
468
472 public override bool CanCopy => true;
473
477 public override void Copy()
478 {
479 Clipboard.SetText("xmpp:" + this.bareJid);
480 }
481 }
482}
Interaction logic for RemoteDesktopView.xaml
Interaction logic for xaml
Abstract base class for tree nodes in the connection view.
Definition: TreeNode.cs:24
TreeNode Parent
Parent node. May be null if a root node.
Definition: TreeNode.cs:107
TreeNode(TreeNode Parent)
Abstract base class for tree nodes in the connection view.
Definition: TreeNode.cs:35
Class representing a normal XMPP account.
Represents an XMPP contact whose capabilities have not been measured.
Definition: XmppContact.cs:24
override async Task SendChatMessage(string Message, string ThreadId, MarkdownDocument Markdown)
Sends a chat message.
Definition: XmppContact.cs:274
virtual bool UseActuatorControl
If actuator control should be used (instead of RDP control)
Definition: XmppContact.cs:419
override async void Configure()
Starts configuration of the node.
Definition: XmppContact.cs:421
override bool CanCopy
If node can be copied to clipboard.
Definition: XmppContact.cs:472
override void Copy()
Is called when the user wants to copy the node to the clipboard.
Definition: XmppContact.cs:477
override void Write(XmlWriter Output)
Saves the object to a file.
Definition: XmppContact.cs:73
override void AddContexMenuItems(ref string CurrentGroup, ContextMenu Menu)
Adds context sensitive menu items to a context menu.
Definition: XmppContact.cs:315
static string GetBody(string Html)
Extracts the contents of the BODY element in a HTML string.
Contains a markdown document. This markdown document class supports original markdown,...
Task< string > GenerateMarkdown()
Generates Markdown from the markdown text.
async Task< string > GeneratePlainText()
Generates Plain Text from the markdown text.
async Task< string > GenerateHTML()
Generates HTML from the markdown text.
Helps with common XML-related tasks.
Definition: XML.cs:19
static string HtmlValueEncode(string s)
Differs from Encode(String), in that it does not encode the aposotrophe or the quote.
Definition: XML.cs:209
static string Encode(string s)
Encodes a string for use in XML.
Definition: XML.cs:27
Event arguments for presence events.
string From
From where the presence was received.
Availability Availability
Resource availability.
Task< RemoteDesktopSession > StartSessionAsync(string To)
Starts a Remote Desktop session.
override void Dispose()
Disposes of the extension.
Maintains information about an item in the roster.
Definition: RosterItem.cs:75
SubscriptionState State
roup Current subscription state.
Definition: RosterItem.cs:268
bool HasLastPresence
If the roster item has received presence from an online resource having the given bare JID.
Definition: RosterItem.cs:425
string LastPresenceFullJid
Full JID of last resource sending online presence.
Definition: RosterItem.cs:343
PresenceEventArgs LastPresence
Last presence received from a resource having this bare JID.
Definition: RosterItem.cs:356
Manages an XMPP client connection. Implements XMPP, as defined in https://tools.ietf....
Definition: XmppClient.cs:59
Task SendMessage(MessageType Type, string To, string CustomXml, string Body, string Subject, string Language, string ThreadId, string ParentThreadId)
Sends a simple chat message
Definition: XmppClient.cs:5395
Task SendChatMessage(string To, string Body)
Sends a simple chat message
Definition: XmppClient.cs:5324
Availability
Resource availability.
Definition: Availability.cs:7
QoSLevel
Quality of Service Level for asynchronous messages. Support for QoS Levels must be supported by the r...
Definition: QoSLevel.cs:8
SubscriptionState
State of a presence subscription.
Definition: RosterItem.cs:16
MessageType
Type of message received.
Definition: MessageType.cs:7