TeamsNetphoneLink/TeamsNetphoneLinkWPF/Syncronisation.cs
2025-03-25 22:43:13 +01:00

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);
}
}
}
}
}