273 lines
12 KiB
C#
273 lines
12 KiB
C#
using System.ComponentModel;
|
|
using System.Windows.Media;
|
|
using TeamsLocalLibary.EventArgs;
|
|
using TeamsNetphoneLink.Teams;
|
|
using TeamsNetphoneLink.Netphone;
|
|
using TeamsNetphoneLink.WPF.MVVM;
|
|
using TeamsNetphoneLink.Communication;
|
|
using System.Reflection;
|
|
using TeamsNetphoneLink.WPF;
|
|
|
|
namespace TeamsNetphoneLink
|
|
{
|
|
public class Syncronisation
|
|
{
|
|
public NetPhoneEvents NetphoneEvents { get; set; }
|
|
public TeamsGraph TeamsGraph { get; set; }
|
|
public TeamsLocalAPI TeamsEvents { get; set; }
|
|
|
|
//MVVM View Models
|
|
public DashboardViewModel _dashboardViewModel { get; }
|
|
public LogViewModel LogEntries { get; }
|
|
public FinishPanelViewModel FinishPanelViewModel { get; }
|
|
|
|
public readonly SemaphoreSlim TeamsGraphAuthenticationSemaphore = new(1);
|
|
|
|
private bool _isCallActive = false;
|
|
private bool _isMeetingActive = false;
|
|
private bool NetphoneConnected = false;
|
|
|
|
|
|
public Syncronisation(NetPhoneEvents netPhoneEvents, TeamsLocalAPI teamsEvents, TeamsGraph teamsGraph, DashboardViewModel dashboardViewModel, LogViewModel logEntries, FinishPanelViewModel finishPanelViewModel)
|
|
{
|
|
_dashboardViewModel = dashboardViewModel ?? throw new ArgumentNullException(nameof(dashboardViewModel));
|
|
LogEntries = logEntries ?? throw new ArgumentNullException(nameof(logEntries));
|
|
FinishPanelViewModel = finishPanelViewModel ?? throw new ArgumentNullException(nameof(finishPanelViewModel));
|
|
NetphoneEvents = netPhoneEvents ?? throw new ArgumentNullException(nameof(netPhoneEvents));
|
|
TeamsEvents = teamsEvents ?? throw new ArgumentNullException(nameof(teamsEvents));
|
|
TeamsGraph = teamsGraph ?? throw new ArgumentNullException(nameof(teamsGraph));
|
|
|
|
// Event-Handler für Netphone-Events registrieren
|
|
NetphoneEvents.AddLineStateEventHandler(LineState.Dialing, NetphoneEventCall);
|
|
NetphoneEvents.AddLineStateEventHandler(LineState.Ringing, NetphoneEventCall);
|
|
NetphoneEvents.AddLineStateEventHandler(LineState.Active, NetphoneEventCall);
|
|
NetphoneEvents.AddLineStateEventHandler(LineState.Inactive, NetphoneEventTerminated);
|
|
NetphoneEvents.AddLineStateEventHandler(LineState.Terminated, NetphoneEventTerminated);
|
|
NetphoneEvents.AddLoggedInStateEventHandler(NetphoneOnLoggedInStateChanged);
|
|
|
|
if (!Settings.Default.UseGraphForMeetingState)
|
|
{
|
|
// Event-Handler für Teams-Events registrieren
|
|
TeamsEvents.AddEventHandler("IsInMeeting", TeamsIsInMeetingHandler);
|
|
TeamsEvents.AddConnectionStateHandler(TeamsOnConnectionStateChanged);
|
|
TeamsEvents.AddTokenRecievedHandler(TeamsTokenRecievedHandler);
|
|
}
|
|
else
|
|
{
|
|
TeamsGraph.ActivityChanged += TeamsGraphOnActivityChanged;
|
|
_dashboardViewModel.UpdateStatusPanel(StatusPanelNames.TeamsLocalAPIStatus, Colors.Orange, "Deaktiviert");
|
|
}
|
|
}
|
|
|
|
// Event-Handler für Änderungen des Verbindungsstatus in Teams
|
|
private void TeamsOnConnectionStateChanged(object? sender, ConnectionStateChangedEventArgs args)
|
|
{
|
|
var status = args.WebSocketState switch
|
|
{
|
|
System.Net.WebSockets.WebSocketState.Open when Settings.Default.TeamsPermission => (Colors.Green, "Verbunden"),
|
|
System.Net.WebSockets.WebSocketState.Open => (Colors.Orange, "Authorisieren (Klicken)"),
|
|
System.Net.WebSockets.WebSocketState.Connecting => (Colors.Blue, "Verbinden..."),
|
|
System.Net.WebSockets.WebSocketState.Closed => (Colors.Red, "Nicht verbunden"),
|
|
_ => (Colors.Gray, "Unbekannt")
|
|
};
|
|
|
|
_dashboardViewModel.UpdateStatusPanel(StatusPanelNames.TeamsLocalAPIStatus, status.Item1, status.Item2);
|
|
|
|
if(Settings.Default.TeamsPermission)
|
|
LogEntries.AddLogEntry(args.WebSocketState == System.Net.WebSockets.WebSocketState.Open ? "Info" : "Warn", "TeamsLocalAPI", status.Item2);
|
|
}
|
|
|
|
private void NetphoneOnLoggedInStateChanged(bool isLoggedIn)
|
|
{
|
|
NetphoneConnected = isLoggedIn;
|
|
|
|
var state = isLoggedIn ? ( Colors.Green, "Verbunden" ) : ( Colors.Red, "Nicht verbunden" );
|
|
|
|
_dashboardViewModel.UpdateStatusPanel(StatusPanelNames.NetphoneCLMGRStatus, state.Item1, state.Item2);
|
|
LogEntries.AddLogEntry(isLoggedIn ? "Info" : "Warn", "Netphone", state.Item2);
|
|
}
|
|
|
|
// Event-Handler für den Empfang eines Teams-Tokens
|
|
private void TeamsTokenRecievedHandler(object sender, TokenReceivedEventArgs e)
|
|
{
|
|
if (!Settings.Default.TeamsPermission)
|
|
{
|
|
Settings.Default.TeamsPermission = true;
|
|
Settings.Default.Save();
|
|
|
|
FinishPanelViewModel.FinishPanelEffect = null;
|
|
FinishPanelViewModel.FinishPanelEnabled = true;
|
|
FinishPanelViewModel.FinishPanelFinishTextText = "Verbindung erfolgreich";
|
|
FinishPanelViewModel.SetFinishPanelFinishTextColor(Colors.Green);
|
|
|
|
_dashboardViewModel.UpdateStatusPanel(StatusPanelNames.TeamsLocalAPIStatus, Colors.Green, "Verbunden");
|
|
LogEntries.AddLogEntry("TeamsLocalAPI", "Token erfolgreich abgerufen");
|
|
}
|
|
}
|
|
|
|
// Event-Handler für eingehende Anrufe
|
|
private async void NetphoneEventCall(LineState newLineState)
|
|
{
|
|
if (_isCallActive) return;
|
|
|
|
_isCallActive = true;
|
|
await TeamsGraph.SetPresenceAsync(TeamsGraph.PresenceState.Busy);
|
|
_dashboardViewModel.UpdateStatusPanel(StatusPanelNames.NetphoneCallStatus, Colors.DarkGreen, "Ongoing");
|
|
LogEntries.AddLogEntry("Syncronisation", "Netphone Anruf gestartet");
|
|
}
|
|
|
|
// Event-Handler für beendete Anrufe
|
|
private async void NetphoneEventTerminated(LineState newLineState)
|
|
{
|
|
if (!_isCallActive) return;
|
|
|
|
_isCallActive = false;
|
|
await TeamsGraph.SetPresenceAsync(TeamsGraph.PresenceState.Available);
|
|
_dashboardViewModel.UpdateStatusPanel(StatusPanelNames.NetphoneCallStatus, Colors.DarkOrange, "Not active");
|
|
LogEntries.AddLogEntry("Syncronisation", "Netphone Anruf gestoppt");
|
|
}
|
|
|
|
|
|
private void TeamsGraphOnActivityChanged(object sender, PresenceChangedEventArgs args)
|
|
{
|
|
// Define activities that indicate the user is in a meeting
|
|
var meetingActivities = new HashSet<string>
|
|
{
|
|
"InACall",
|
|
"InAConferenceCall",
|
|
"InAMeeting",
|
|
"Presenting"
|
|
};
|
|
|
|
if(args.Presence.Activity is null)
|
|
return;
|
|
|
|
// Check if the current activity is in the meetingActivities set
|
|
bool isInMeeting = meetingActivities.Contains(args.Presence.Activity);
|
|
|
|
|
|
if (!isInMeeting && _isMeetingActive)
|
|
{
|
|
_isMeetingActive = false;
|
|
SetNetphoneStatus(isInMeeting);
|
|
return;
|
|
}
|
|
|
|
if (isInMeeting && !_isMeetingActive)
|
|
{
|
|
_isMeetingActive = true;
|
|
SetNetphoneStatus(isInMeeting);
|
|
}
|
|
}
|
|
|
|
// Event-Handler für Änderungen des "IsInMeeting"-Status in Teams
|
|
private void TeamsIsInMeetingHandler(object sender, PropertyChangedEventArgs e)
|
|
{
|
|
var isInMeeting = (bool)(sender.GetType()?.GetProperty(e.PropertyName)?.GetValue(sender) ?? false);
|
|
SetNetphoneStatus(isInMeeting);
|
|
}
|
|
|
|
private void SetNetphoneStatus(bool meeting)
|
|
{
|
|
if (meeting)
|
|
{
|
|
if (NetphoneConnected)
|
|
{
|
|
NetphoneEvents.SetRichPresenceStatus(0, 1, DateTime.MaxValue);
|
|
NetphoneEvents.SetAppointmentText("In einem Teams Meeting", DateTime.MaxValue);
|
|
}
|
|
_dashboardViewModel.UpdateStatusPanel(StatusPanelNames.TeamsMeetingStatus, Colors.DarkGreen, "Ongoing");
|
|
LogEntries.AddLogEntry("Syncronisation", "Teams Meeting gestartet");
|
|
}
|
|
else
|
|
{
|
|
if (NetphoneConnected)
|
|
{
|
|
NetphoneEvents.SetRichPresenceStatus(0, 0, DateTime.MaxValue);
|
|
NetphoneEvents.SetAppointmentText("", DateTime.MaxValue);
|
|
}
|
|
_dashboardViewModel.UpdateStatusPanel(StatusPanelNames.TeamsMeetingStatus, Colors.DarkOrange, "Not active");
|
|
LogEntries.AddLogEntry("Syncronisation", "Teams Meeting gestoppt");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Methode zur Authentifizierung bei der Graph API
|
|
public async Task<bool> GraphAuthenticate(bool clearCache = false)
|
|
{
|
|
_dashboardViewModel.UpdateStatusPanel(StatusPanelNames.TeamsGraphAPIStatus, Colors.Blue, "Anmeldung läuft...");
|
|
LogEntries.AddLogEntry("TeamsGraphAPI", String.Format("Anmeldung läuft"));
|
|
|
|
var authResult = await TeamsGraph.AuthenticateAsync(clearCache);
|
|
|
|
var status = authResult ? (Colors.Green, "Angemeldet") : (Colors.Red, "Fehler - Anmelden (Klicken)");
|
|
_dashboardViewModel.UpdateStatusPanel(StatusPanelNames.TeamsGraphAPIStatus, status.Item1, status.Item2);
|
|
LogEntries.AddLogEntry("TeamsGraphAPI", status.Item2);
|
|
|
|
return authResult;
|
|
}
|
|
|
|
public async void InitializeNetphoneAsync()
|
|
{
|
|
try
|
|
{
|
|
await this.NetphoneEvents.Initialize(waitForNetphone: true).ConfigureAwait(false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Fehlerbehandlung für die Netphone-Initialisierung
|
|
ExceptionWindowHelper.Show(this.GetType().Name, MethodBase.GetCurrentMethod().Name, "Fehler bei der Initialisierung von der NetphoneAPI", ex.Message, ex.StackTrace);
|
|
}
|
|
}
|
|
|
|
public async void InitializeTeamsGraphAsync()
|
|
{
|
|
if (!Teams.TeamsGraph.IsGuid(Settings.Default.AppID) || !Teams.TeamsGraph.IsGuid(Settings.Default.TenantID))
|
|
{
|
|
this._dashboardViewModel.UpdateStatusPanel(StatusPanelNames.TeamsGraphAPIStatus, Colors.Red, "Konfiguration fehlt");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
await this.TeamsGraphAuthenticationSemaphore.WaitAsync().ConfigureAwait(false);
|
|
if (await this.TeamsGraph.IsCachedAccounts() && Settings.Default.SaveEntraCredentials)
|
|
{
|
|
await this.GraphAuthenticate().ConfigureAwait(false); ;
|
|
}
|
|
else
|
|
{
|
|
this._dashboardViewModel.UpdateStatusPanel(StatusPanelNames.TeamsGraphAPIStatus, Colors.Orange, "Anmelden");
|
|
}
|
|
this.TeamsGraphAuthenticationSemaphore.Release();
|
|
|
|
if (Settings.Default.UseGraphForMeetingState)
|
|
{
|
|
this.TeamsGraph.CheckPresenceStatusTimer();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Fehlerbehandlung für die TeamsGraph-Initialisierung
|
|
ExceptionWindowHelper.Show(this.GetType().Name, MethodBase.GetCurrentMethod().Name, "Fehler bei der Initialisierung von TeamsGraph", ex.Message, ex.StackTrace);
|
|
}
|
|
}
|
|
|
|
public async void InitializeTeamsLocalAPIAsync()
|
|
{
|
|
if (!Settings.Default.UseGraphForMeetingState)
|
|
{
|
|
try
|
|
{
|
|
await this.TeamsEvents.Initialize().ConfigureAwait(false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Fehlerbehandlung für die TeamsLocalAPI-Initialisierung
|
|
ExceptionWindowHelper.Show(this.GetType().Name, MethodBase.GetCurrentMethod().Name, "Fehler bei der Initialisierung von der TeamsLocalAPI", ex.Message, ex.StackTrace);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |