Text zu Datei hinzufügen

Neues Buttondesign
Stapelnachrichtsmodus
Anpassbarer Waitlayer
Eigene MessageBox
This commit is contained in:
LynJet
2022-07-28 19:18:15 +02:00
parent b6ccd4fd71
commit b342974c98
35 changed files with 1079 additions and 655 deletions

View File

@@ -61,7 +61,7 @@
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<Label Content="Daten werden übertragen. Bitte warten..." Foreground="#FF000000" FontSize="12" FontFamily="Microsoft Sans Serif" FontWeight="Normal" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Label Content="{Binding DialogText, UpdateSourceTrigger=PropertyChanged}" Foreground="#FF000000" FontSize="12" FontFamily="Microsoft Sans Serif" FontWeight="Normal" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Grid Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Width="40" Height="40" x:Name="bSLogoControl" RenderTransformOrigin="0.5,0.5" Background="#00000000" >
<Grid.RenderTransform>

View File

@@ -1,10 +1,38 @@
namespace ChatController
using System.ComponentModel;
using System.Runtime.CompilerServices;
using ChatController.Annotations;
namespace ChatController
{
public partial class ChatControlWaitLayer
public partial class ChatControlWaitLayer : INotifyPropertyChanged
{
public ChatControlWaitLayer()
private string _DialogText;
public string DialogText
{
get => _DialogText;
set
{
_DialogText = value;
OnPropertyChanged(nameof(DialogText));
}
}
public ChatControlWaitLayer(string dialogText = null)
{
InitializeComponent();
DataContext = this;
DialogText = dialogText ?? "Daten werden übertragen. Bitte warten...";
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -68,6 +68,7 @@
</Compile>
<Compile Include="Converter\BoolToVisibilityConverter.cs" />
<Compile Include="Converter\BroadcastCheckBoxVisibilityMultiConverter.cs" />
<Compile Include="Converter\OwnChatNullVisibilityConverter.cs" />
<Compile Include="Converter\StringEmptyToVisibilityConverter.cs" />
<Compile Include="Converter\StringToBoolConverter.cs" />
<Compile Include="Converter\UserProfilePictureVisibilityConverter.cs" />
@@ -100,7 +101,10 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resource.resx</DependentUpon>
</Compile>
<Compile Include="Utilities\BroadcastMessage.cs" />
<Compile Include="OwnChatMessageBox.xaml.cs">
<DependentUpon>OwnChatMessageBox.xaml</DependentUpon>
</Compile>
<Compile Include="Utilities\ChatMessageFileWrapper.cs" />
<Compile Include="Utilities\BroadcastProgressReportModel.cs" />
<Compile Include="Utilities\Constants.cs" />
<Compile Include="Utilities\Extensions\ControlExtensions.cs" />
@@ -130,6 +134,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="OwnChatMessageBox.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Resource Include="Ressourcen\BeyondsoftChat.jpg" />
@@ -153,6 +161,13 @@
</ItemGroup>
<ItemGroup>
<Content Include="ownchat_favicon.ico" />
<Resource Include="Ressourcen\times-solid.png" />
<Resource Include="Ressourcen\tasks-solid-inverted.png" />
<Resource Include="Ressourcen\tasks-solid.png" />
<Resource Include="Ressourcen\paper-plane-solid.png" />
<Resource Include="Ressourcen\paperclip-solid.png" />
<Resource Include="Ressourcen\smile-regular.png" />
<Resource Include="Ressourcen\sync-alt.png" />
<Resource Include="Ressourcen\TasksSolid.png" />
<Resource Include="Ressourcen\ownchat_image_placeholder.png" />
<Resource Include="Ressourcen\warning-exclamation-mark.png" />

View File

@@ -70,7 +70,7 @@ namespace ChatController.ChatKlassen
OriginalImage = originalImage;
OriginalImageName = imageName;
if(MessageId == 0 && MessageType == ChatMessageType.Image && logo != null)
if(MessageId == 0 && MessageType == ChatMessageType.Image && !(logo is null))
{
PictureSource = logo;
PicturePlaceholderHeight = (int) logo.Height;
@@ -81,9 +81,7 @@ namespace ChatController.ChatKlassen
if(!string.IsNullOrWhiteSpace(thumbnailPath))
{
ThumbnailPlaceholderHeight = Utils.GetHeightFromThumbnailUri(thumbnailPath);
Thumbnail = Utils.GetPicturePlaceholder();
Utils.DownloadImageAsync(thumbnailPath, $"group-{groupId}", CacheCategory.Thumbnail, imageSource =>
Utils.DownloadDocumentThumbnail(thumbnailPath, imageSource =>
{
Thumbnail = imageSource;
});
@@ -208,17 +206,7 @@ namespace ChatController.ChatKlassen
public override bool Equals(object obj)
{
if(obj is ChatMessage message)
{
if(message.IsSeparator && IsSeparator)
{
return SendTime == message.SendTime;
}
return Id.Equals(message.Id) && MessageId.Equals(message.MessageId);
}
return false;
return obj is ChatMessage message && (message.IsSeparator && IsSeparator ? SendTime == message.SendTime : Id.Equals(message.Id) && MessageId.Equals(message.MessageId));
}
public override string ToString()

View File

@@ -54,14 +54,7 @@ namespace ChatController.ChatKlassen
var isOwnMessage = rmUserId.HasValue && rmUserId.Value.Equals(userId);
if (_HasUnreadMessages && !isOwnMessage)
{
_Color = new BrushConverter().ConvertFromString("#ff5e00") as SolidColorBrush;
}
else
{
_Color = new SolidColorBrush(Colors.Gray);
}
_Color = _HasUnreadMessages && !isOwnMessage ? new BrushConverter().ConvertFromString("#FF5A00") as SolidColorBrush : new SolidColorBrush(Colors.Gray);
OnPropertyChanged(nameof(HasUnreadMessages));
OnPropertyChanged(nameof(Color));
@@ -135,22 +128,7 @@ namespace ChatController.ChatKlassen
{
if(obj is Contact y)
{
if(ReferenceEquals(this, y))
{
return true;
}
if(GetType() != y.GetType())
{
return false;
}
return Name == y.Name &&
IsNewMessage == y.IsNewMessage &&
TimeStamp.Equals(y.TimeStamp) &&
GroupId == y.GroupId &&
UserIdManage == y.UserIdManage &&
IsChatMessageInputGridVisible == y.IsChatMessageInputGridVisible;
return GroupId == y.GroupId;
}
return false;
@@ -160,16 +138,21 @@ namespace ChatController.ChatKlassen
{
unchecked
{
var hashCode = Name != null ? Name.GetHashCode() : 0;
var hashCode = Name?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ GroupId;
hashCode = (hashCode * 397) ^ (UserIdManage != null ? UserIdManage.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (UserIdManage?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ IsChatMessageInputGridVisible.GetHashCode();
return hashCode;
}
}
public override string ToString()
{
return $"({GroupId}) {Name}";
}
public SolidColorBrush AccentColorBrush { get; }
public event PropertyChangedEventHandler PropertyChanged;

View File

@@ -11,15 +11,14 @@
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600"
Loaded="ChatMainControl_OnLoaded"
SnapsToDevicePixels="True" d:DataContext="{d:DesignData ChatMainControl}">
SnapsToDevicePixels="True" d:DataContext="{d:DesignData Type=ChatMainControl}">
<UserControl.Resources>
<converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<converter:StringEmptyToVisibilityConverter x:Key="StringEmptyToVisibilityConverter" />
<converter:UserProfilePictureVisibilityConverter x:Key="UserProfilePictureVisibilityConverter" />
<converter:BroadcastCheckBoxVisibilityMultiConverter x:Key="BroadcastCheckBoxVisibilityMultiConverter" />
<converter:OwnChatNullVisibilityConverter x:Key="OwnChatNullVisibilityConverter" />
<!--<SolidColorBrush x:Key="DarkBackColor" Color="#A9B8C2" />-->
<SolidColorBrush x:Key="DarkBackColor" Color="#A9B8C2" />
<SolidColorBrush x:Key="LightBackColor" Color="#F3F3F3" />
@@ -49,84 +48,31 @@
</Setter>
</Style>
<Style x:Key="CloseButtonStyle" TargetType="{x:Type Button}">
<Setter Property="MinWidth" Value="0" />
<Setter Property="MinHeight" Value="0" />
<Setter Property="Width" Value="Auto" />
<Setter Property="Height" Value="Auto" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Focusable" Value="false" />
<Style x:Key="OrangeToggleButtonStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="BorderBrush" Value="#FF5A00" />
<Setter Property="Background" Value="#FF5A00" />
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Resources>
<Storyboard x:Key="Timeline1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="glow" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)" To="1.3" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" To="1.3" Duration="0:0:0.2" />
</Storyboard>
<Storyboard x:Key="Timeline2">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="glow" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" Duration="0:0:0.2" />
</Storyboard>
</ControlTemplate.Resources>
<Grid SnapsToDevicePixels="true" x:Name="grid" MinWidth="20" MinHeight="20">
<Border x:Name="border" BorderBrush="#FF000000" BorderThickness="1,1,1,1" CornerRadius="3,3,3,3" Padding="0,0,0,0" Margin="0,0,0,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF450202" Offset="0" />
<GradientStop Color="#FFC61A1A" Offset="1" />
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.5*" />
<RowDefinition Height="0.5*" />
</Grid.RowDefinitions>
<Border Opacity="0" HorizontalAlignment="Stretch" x:Name="glow" Width="Auto" Grid.RowSpan="2" CornerRadius="3,3,3,3">
<Border.Background>
<RadialGradientBrush>
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.702" ScaleY="2.243" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="-0.368" Y="-0.152" />
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Color="#B2FFFFFF" Offset="0" />
<GradientStop Color="#00FF9E9A" Offset="1" />
</RadialGradientBrush>
</Border.Background>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="Border" Background="#FF5A00" CornerRadius="5" Padding="5,2">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<Border Grid.Row="0" HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="shine" Width="Auto" CornerRadius="3,3,0,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#99FFFFFF" Offset="0" />
<GradientStop Color="#33FFFFFF" Offset="1" />
</LinearGradientBrush>
</Border.Background>
</Border>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Webdings" FontSize="16" Foreground="#FFFFFFFF" TextWrapping="Wrap"
Grid.Row="0" Grid.RowSpan="2">
<Run Text="r" />
</TextBlock>
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Timeline1}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard x:Name="Timeline2_BeginStoryboard" Storyboard="{StaticResource Timeline2}" />
</Trigger.ExitActions>
<Setter Property="Background" Value="#FF988F" TargetName="Border" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#FF7654" TargetName="Border" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="LightGray" TargetName="Border" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" Value="#FF5A00" TargetName="Border" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="#FFFFFF" TargetName="Border" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
@@ -171,6 +117,7 @@
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="ContactListBoxTemplate" TargetType="{x:Type ListBox}">
<Border x:Name="Bd" SnapsToDevicePixels="True" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
<ScrollViewer Focusable="False" Padding="{TemplateBinding Padding}" Style="{StaticResource MainNavigationScrollViewer}" HorizontalScrollBarVisibility="Disabled">
@@ -178,6 +125,7 @@
</ScrollViewer>
</Border>
</ControlTemplate>
<Style x:Key="ContactListStyle" TargetType="{x:Type ListBox}">
<Setter Property="Template" Value="{StaticResource ContactListBoxTemplate}" />
</Style>
@@ -186,12 +134,12 @@
<Style x:Key="ContactListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorLevel=1, AncestorType={x:Type ItemsControl}, Mode=FindAncestor}}" />
<Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorLevel=1, AncestorType={x:Type ItemsControl}, Mode=FindAncestor}}" />
<Setter Property="Margin" Value="0,0,0,0" />
<Setter Property="Margin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Border x:Name="ItemBorder" MinHeight="20" Background="White" BorderThickness="0,0,0,0" BorderBrush="{StaticResource LightBackColor}">
<Border x:Name="ItemBorder" MinHeight="20" Background="White" BorderThickness="0" BorderBrush="{StaticResource LightBackColor}">
</Border>
<Border x:Name="ItemContent" MinHeight="20">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5,3,5,3" OpacityMask="{x:Null}" SnapsToDevicePixels="True">
@@ -269,8 +217,8 @@
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="1" x:Name="PART_ContentHost" Margin="0,2,0,0" />
<Canvas Grid.Column="0" Width="14" Margin="3,4,2,2">
<Ellipse Stroke="#FFA0A0A0" Height="10" Width="10" StrokeThickness="2" Fill="{x:Null}" />
<Line Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FFA0A0A0" Canvas.Left="6" Canvas.Top="7.4" Y1="0" Y2="5" StrokeThickness="3" X2="4" />
<Ellipse Stroke="#A0A0A0" Height="10" Width="10" StrokeThickness="2" Fill="{x:Null}" />
<Line Fill="#FFFFFF" Stretch="Fill" Stroke="#A0A0A0" Canvas.Left="6" Canvas.Top="7.4" Y1="0" Y2="5" StrokeThickness="3" X2="4" />
</Canvas>
</Grid>
</Border>
@@ -289,6 +237,9 @@
<Setter Property="Height" Value="40" />
</Style>
</UserControl.Resources>
<Grid x:Name="RootGrid">
<Border x:Name="rootBorder" Background="{StaticResource DarkBackColor}" Padding="0" Margin="0" BorderThickness="0">
<Grid>
@@ -319,19 +270,24 @@
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel x:Name="ReloadGruppen" Grid.Row="0" Grid.Column="1" Height="25" HorizontalAlignment="Right" Orientation="Horizontal" VerticalAlignment="Center" Visibility="Visible" Margin="0,0,3,0">
<StackPanel x:Name="ReloadGruppen" Grid.Row="0" Grid.Column="1" Height="25"
HorizontalAlignment="Right" Orientation="Horizontal" VerticalAlignment="Center" Visibility="Visible" Margin="0,0,3,0">
<Button Background="Transparent" HorizontalAlignment="Right" BorderThickness="0"
Style="{StaticResource OrangeButtonStyle}"
VerticalAlignment="Center" VerticalContentAlignment="Center" Width="25" Height="25" Click="ButtonReloadGruppen_OnClick" >
<Image ToolTip="Gruppen Aktualisieren" Margin="0,0,0,0" Width="20" Height="20"
Source="pack://application:,,,/ChatController;component/Ressourcen/SymbolRefresh32.png" RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
</Button>
<Button HorizontalAlignment="Right" Background="Transparent" VerticalAlignment="Center" VerticalContentAlignment="Center"
Click="BroadcastButton_OnClick" Style="{StaticResource OrangeButtonStyle}" Margin="5,0,0,0">
<Image ToolTip="Nachricht an mehrere Empfänger schicken" Margin="0" Width="20" Height="20"
Source="pack://application:,,,/ChatController;component/Ressourcen/TasksSolid.png" RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
<Image ToolTip="Gruppen Aktualisieren" Margin="0,0,0,0"
Source="pack://application:,,,/ChatController;component/Ressourcen/sync-alt.png"
RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
</Button>
<!-- In toggleButton ändern -->
<ToggleButton HorizontalAlignment="Right" Background="Transparent" VerticalAlignment="Center" VerticalContentAlignment="Center"
Width="25" Height="25" Style="{StaticResource OrangeToggleButtonStyle}" x:Name="BroadcastToggleButton"
Click="BroadcastToggleButton_OnClick" Margin="5,0,0,0">
<Image ToolTip="Nachricht an mehrere Empfänger schicken" Margin="0" x:Name="ToggleButtonImage"
Source="pack://application:,,,/ChatController;component/Ressourcen/tasks-solid.png"
RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
</ToggleButton>
</StackPanel>
<TextBox Grid.Column="0" x:Name="Suche" Height="22" HorizontalAlignment="Stretch" Margin="5" TabIndex="0" Template="{DynamicResource SearchTextBoxTemplate}" BorderThickness="0,0,0,0" TextChanged="Suche_OnTextChanged" />
</Grid>
<!-- endregion Gruppensuche und Gruppenliste aktualisieren -->
@@ -339,19 +295,19 @@
<!-- region Kontaktliste -->
<Grid Grid.Column="0" Grid.Row="1" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox Grid.Row="0" Margin="5" x:Name="SelectAllContactsCheckBox" FontSize="16" Content="Alle auswählen" VerticalAlignment="Center" Height="35"
Click="SelectAllContacts_OnClick"
Visibility="{Binding Path=Chat.IsInBroadcastMode, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}" />
<ListView x:Name="Clientlist" HorizontalAlignment="Stretch" Grid.Row="1" Grid.Column="0" VerticalAlignment="Stretch" BorderThickness="0" Background="White"
<ListView x:Name="Clientlist" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="0" VerticalAlignment="Stretch" BorderThickness="0" Background="White"
ItemsSource="{Binding ContactList, UpdateSourceTrigger=PropertyChanged}"
ItemContainerStyle="{StaticResource ContactListBoxItemStyle}" SelectionChanged="Clientlist_OnSelectionChanged" Style="{StaticResource ContactListStyle}">
</ListView>
<CheckBox Grid.Row="1" Margin="5" x:Name="SelectAllContactsCheckBox" FontSize="16" Content="Alle auswählen" VerticalAlignment="Center"
Click="SelectAllContacts_OnClick" VerticalContentAlignment="Center"
Visibility="{Binding Path=Chat.IsInBroadcastMode, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}" />
</Grid>
<!-- endregion Kontaktliste -->
</Grid>
@@ -366,7 +322,18 @@
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" HorizontalAlignment="Left" Background="Transparent" VerticalAlignment="Center" Height="50" PreviewMouseDown="CurrentContactImage_OnMouseDoubleClick">
<!-- #region Fortschrittsoverlay -->
<StackPanel Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" VerticalAlignment="Center" HorizontalAlignment="Stretch"
Orientation="Vertical" Visibility="{Binding Path=ProgressOverlayVisibility, UpdateSourceTrigger=PropertyChanged}">
<ProgressBar Margin="20, 5" Value="{Binding BroadcastProgressValue, UpdateSourceTrigger=PropertyChanged}" Height="20" />
<Button Content="Abbrechen" Width="75" Style="{StaticResource OrangeButtonStyle}" Height="25" Margin="0, 5"
Click="CancelBroadcastButton_OnClick" />
</StackPanel>
<!-- #endregion Fortschrittsoverlay -->
<Grid Grid.Row="0" HorizontalAlignment="Left" Background="Transparent"
Visibility="{Binding Path=NormalViewVisibility, UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center" Height="50" PreviewMouseDown="CurrentContactImage_OnMouseDoubleClick">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
@@ -396,7 +363,7 @@
Background="{StaticResource LightBackColor}"
ContextMenuOpening="Chat_OnContextMenuOpening"
Padding="20"
Visibility="{Binding Path=Chat.IsInBroadcastMode, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type chatController:ChatMainControl}}, Converter={StaticResource BoolToVisibilityConverter}}"
Visibility="{Binding Path=ChatListBoxVisibility, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type chatController:ChatMainControl}}}"
d:DataContext="{d:DesignData ChatMessage}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
@@ -458,6 +425,7 @@
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- #region Fremdes Profilbild in Gruppenchat -->
<Ellipse Grid.Column="0"
Margin="2,5,2,2" VerticalAlignment="Top" Width="32" Height="32" RenderOptions.BitmapScalingMode="HighQuality">
<Ellipse.Fill>
@@ -470,11 +438,15 @@
</MultiBinding>
</Ellipse.Visibility>
</Ellipse>
<!-- #endregion Fremdes Profilbild in Gruppenchat -->
<Separator Grid.Column="0" Grid.ColumnSpan="2" Visibility="{Binding IsSeparator, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}" VerticalContentAlignment="Center" />
<Label Content="{Binding SeparatorTimeString}" HorizontalAlignment="Center" Grid.Column="2" Visibility="{Binding IsSeparator, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}" />
<Separator Grid.Column="3" Grid.ColumnSpan="2" Visibility="{Binding IsSeparator, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}" />
<!-- #region Separator -->
<Separator Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Stretch" Visibility="{Binding IsSeparator, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}" VerticalContentAlignment="Center" />
<Label VerticalAlignment="Center" Content="{Binding SeparatorTimeString}" HorizontalAlignment="Center" Grid.Column="2" Visibility="{Binding IsSeparator, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}" />
<Separator Grid.Column="3" Grid.ColumnSpan="2" HorizontalAlignment="Stretch" Visibility="{Binding IsSeparator, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}" VerticalContentAlignment="Center" />
<!-- #endregion Separator -->
<!-- #region DockPanel mit Nachricht und gegebenenfalls Datei -->
<DockPanel Grid.Column="1" Grid.ColumnSpan="3" MinHeight="15" Margin="5" LastChildFill="True" Visibility="{Binding IsSeparator, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel DockPanel.Dock="Bottom" Orientation="Vertical">
<Image ToolTip="Dokument öffnen" Height="{Binding ThumbnailPlaceholderHeight, UpdateSourceTrigger=PropertyChanged}" Width="150"
@@ -495,7 +467,9 @@
<TextBlock Text="{Binding UserTimeStringRight}" MaxWidth="{Binding TimeStringMaxWidth}" FontSize="11" HorizontalAlignment="Right" TextAlignment="Right" VerticalAlignment="Center" Foreground="{Binding Foreground}" />
</StackPanel>
</DockPanel>
<!-- #endregion DockPanel mit Nachricht und gegebenenfalls Datei -->
<!-- #region Eigenes Profilbild in Gruppenchat -->
<Ellipse Grid.Column="4"
Margin="2,5,2,2" VerticalAlignment="Top" Width="32" Height="32" RenderOptions.BitmapScalingMode="HighQuality">
<Ellipse.Fill>
@@ -508,6 +482,7 @@
</MultiBinding>
</Ellipse.Visibility>
</Ellipse>
<!-- #endregion Eigenes Profilbild in Gruppenchat -->
</Grid>
</Border>
</StackPanel>
@@ -515,24 +490,52 @@
</ListBox.ItemTemplate>
</ListBox>
<Grid Grid.Row="1" Grid.Column="0" Visibility="{Binding Path=Chat.IsInBroadcastMode, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0" Margin="5" Height="20" Width="20" HorizontalAlignment="Right" Style="{DynamicResource CloseButtonStyle}" Click="AbortBroadcastButton_OnClick" />
<StackPanel Grid.Row="1" Orientation="Vertical" Margin="5" VerticalAlignment="Center">
<!-- #region Stapelmodus/Textbox-Ansicht -->
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Grid.Row="1" Grid.Column="0" Visibility="{Binding Path=StapelmodusChatGridVisibility, UpdateSourceTrigger=PropertyChanged}">
<Grid>
<Button Width="25" Height="25" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="5,0,5,5"
ToolTip="Angehängte Datei entfernen"
Visibility="{Binding Path=RemoveFileFromBroadcastMessageVisibility, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource OrangeButtonStyle}" Click="RemoveBroadcastFileAttachmentButton_Click">
<Image Source ="pack://application:,,,/ChatController;component/Ressourcen/times-solid.png"
RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
</Button>
<StackPanel Orientation="Vertical" Margin="5" VerticalAlignment="Center">
<TextBlock Text="{Binding BroadcastInfoText, UpdateSourceTrigger=PropertyChanged}" Foreground="Black"
HorizontalAlignment="Center" TextWrapping="Wrap" TextAlignment="Center" FontSize="16" Margin="20, 0" />
<ProgressBar Margin="20, 5" Value="{Binding BroadcastProgressValue, UpdateSourceTrigger=PropertyChanged}" Height="20" />
<Image MaxHeight="300" RenderOptions.BitmapScalingMode="HighQuality"
Source="{Binding Path=BroadcastMessage.BroadcastMessageImageSource, UpdateSourceTrigger=PropertyChanged}" Stretch="Uniform"
/>
<Button Content="Abbrechen" Width="75" Style="{StaticResource OrangeButtonStyle}" Height="25" Margin="0, 5"
Click="CancelBroadcastButton_OnClick" />
<Image MaxHeight="300" RenderOptions.BitmapScalingMode="HighQuality" Margin="5"
Source="{Binding Path=BroadcastMessageFileWrapper.ChatMessageImageSource, UpdateSourceTrigger=PropertyChanged}" Stretch="Uniform" />
<TextBlock Text="{Binding Path=BroadcastMessageFileWrapper.FileName, UpdateSourceTrigger=PropertyChanged}"
FontSize="16" HorizontalAlignment="Center" Foreground="Black" />
</StackPanel>
</Grid>
</ScrollViewer>
<!-- #endregion Stapelmodus/Textbox-Ansicht -->
<!-- #region Normalmodus/Dateivorschau -->
<Grid Grid.Row="1" Grid.Column="0" Visibility="{Binding Path=FilePreviewGridVisibility, UpdateSourceTrigger=PropertyChanged}">
<ScrollViewer HorizontalScrollBarVisibility="Disabled">
<Grid>
<Button Width="25" Height="25" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="5,0,5,5"
ToolTip="Angehängte Datei entfernen"
Style="{StaticResource OrangeButtonStyle}" Click="RemoveFileAttachmentButton_Click">
<Image Source ="pack://application:,,,/ChatController;component/Ressourcen/times-solid.png"
RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
</Button>
<StackPanel Orientation="Vertical" Margin="5" VerticalAlignment="Center">
<Image MaxHeight="300" RenderOptions.BitmapScalingMode="HighQuality"
Source="{Binding Path=ChatMessageFileWrapper.ChatMessageImageSource, UpdateSourceTrigger=PropertyChanged}" Stretch="Uniform" />
<TextBlock Text="{Binding Path=ChatMessageFileWrapper.FileName, UpdateSourceTrigger=PropertyChanged}"
FontSize="16" HorizontalAlignment="Center" Foreground="Black" />
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
<!-- #endregion Normalmodus/Dateivorschau -->
<!-- #region Nachrichtentextbox -->
<Grid Grid.Row="2" Visibility="{Binding ChatMessageInputGridVisibility}" VerticalAlignment="Stretch" MinHeight="25" MaxHeight="200">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
@@ -584,29 +587,47 @@
</TextBlock.Resources>
</TextBlock>
<Button Grid.Column="1" Margin="2" x:Name="MediaButton" Background="Transparent"
Width="28" Height="28" BorderThickness="0" Padding="2"
Width="25" Height="25" BorderThickness="0" Padding="2"
Visibility="{Binding Chat.IsInBroadcastMode, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolToVisibilityConverter}}"
VerticalAlignment="Bottom" ToolTip="Datei einfügen" Click="MediaButton_OnClick" >
<Image Width="22" Height="22" Source='pack://application:,,,/ChatController;component/Ressourcen/paperclip2.png' RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center"/>
VerticalAlignment="Bottom" ToolTip="Datei einfügen" Click="MediaButton_OnClick"
Style="{StaticResource OrangeButtonStyle}">
<Image Source='pack://application:,,,/ChatController;component/Ressourcen/paperclip-solid.png'
RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center"/>
</Button>
<Button Grid.Column="1" Margin="2" Background="Transparent"
Width="28" Height="28" BorderThickness="0" Padding="2"
<Button Grid.Column="1" Margin="3" Style="{StaticResource OrangeButtonStyle}" Width="25" Height="25"
Visibility="{Binding Path=Chat.IsInBroadcastMode, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}"
VerticalAlignment="Bottom" ToolTip="Datei einfügen" Click="AddMediaFileToBroadcastMessage_OnClick">
<Image Width="22" Height="22" Source="pack://application:,,,/ChatController;component/Ressourcen/paperclip2.png" RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
<Image Source='pack://application:,,,/ChatController;component/Ressourcen/paperclip-solid.png'
RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
</Button>
<Button Grid.Column="2" Width="28" Height="28" BorderThickness="0"
Background="Transparent" x:Name="EmojiButton" Margin="2" Padding="0"
VerticalAlignment="Bottom" ToolTip="Emoji einfügen" Click="EmojiButton_OnClick">
<Image Width="24" Height="24" Source='pack://application:,,,/ChatController;component/Ressourcen/glucklicher.png' RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
<!-- Emoji-Button -->
<Button Grid.Column="2" Width="25" Height="25" x:Name="EmojiButton"
Margin="3" VerticalAlignment="Bottom" ToolTip="Emoji einfügen"
Style="{StaticResource OrangeButtonStyle}"
Click="EmojiButton_OnClick">
<Image Source='pack://application:,,,/ChatController;component/Ressourcen/smile-regular.png'
RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
</Button>
<Button x:Name="SendButton" Height="25" Content="Senden" Margin="3" Grid.Column="3" VerticalAlignment="Bottom" Style="{StaticResource OrangeButtonStyle}"
<!-- Senden Button -->
<Button Height="25" Width="25" Margin="3" Grid.Column="3" VerticalAlignment="Bottom"
Style="{StaticResource OrangeButtonStyle}"
Visibility="{Binding Chat.IsInBroadcastMode, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolToVisibilityConverter}}"
Click="SendButton_OnClick" IsEnabled="{Binding IsSendButtonEnabled, UpdateSourceTrigger=PropertyChanged}" />
<Button Height="25" Content="Senden" Margin="3" Grid.Column="3" VerticalAlignment="Bottom" Style="{StaticResource OrangeButtonStyle}"
Click="SendButton_OnClick"
IsEnabled="{Binding IsSendButtonEnabled, UpdateSourceTrigger=PropertyChanged}">
<Image Source="pack://application:,,,/ChatController;component/Ressourcen/paper-plane-solid.png"
RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
</Button>
<!-- Broadcast Senden Button -->
<Button Height="25" Width="25" Margin="3" Grid.Column="3" VerticalAlignment="Bottom"
Style="{StaticResource OrangeButtonStyle}"
Visibility="{Binding Path=Chat.IsInBroadcastMode, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}"
Click="SendBroatcastButton_OnClick" IsEnabled="{Binding IsBroadcastButtonEnabled, UpdateSourceTrigger=PropertyChanged}" />
Click="SendBroatcastButton_OnClick"
IsEnabled="{Binding IsBroadcastButtonEnabled, UpdateSourceTrigger=PropertyChanged}">
<Image Source="pack://application:,,,/ChatController;component/Ressourcen/paper-plane-solid.png"
RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
</Button>
</Grid>
<!-- #endregion Nachrichtentextbox -->
</Grid>
</Grid>
</Border>

View File

@@ -67,9 +67,9 @@ namespace ChatController
private readonly ImageSource _ThreadExceptionImageSource;
public ImageSource ThreadExceptionImageSource => ThreadExceptionMessage != null ? _ThreadExceptionImageSource : CurrentContact?.Image;
public ImageSource ThreadExceptionImageSource => !(ThreadExceptionMessage is null) ? _ThreadExceptionImageSource : CurrentContact?.Image;
public SolidColorBrush CurrencContactInfoForeground => ThreadExceptionMessage != null ? new SolidColorBrush(Color.FromRgb(185, 65, 0)) : CurrentContact?.AccentColorBrush ?? new SolidColorBrush(Colors.Transparent);
public SolidColorBrush CurrencContactInfoForeground => !(ThreadExceptionMessage is null) ? new SolidColorBrush(Color.FromRgb(185, 65, 0)) : CurrentContact?.AccentColorBrush ?? new SolidColorBrush(Colors.Transparent);
public string CurrentContactInformationString => ThreadExceptionMessage ?? CurrentContact?.Name;
@@ -83,7 +83,7 @@ namespace ChatController
{
_ContainingWindow = value;
if(value != null)
if(!(value is null))
{
_ContainingWindow.Deactivated += ContainingWindowOnDeactivated;
_ContainingWindow.Activated += ContainingWindowOnActivated;
@@ -91,7 +91,21 @@ namespace ChatController
}
}
public Chat Chat { get; set; }
private Chat _Chat;
public Chat Chat
{
get => _Chat;
set
{
_Chat = value;
OnPropertyChanged(nameof(Chat));
OnPropertyChanged(nameof(ChatMessageInputGridVisibility));
OnPropertyChanged(nameof(ChatListBoxVisibility));
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
OnPropertyChanged(nameof(StapelmodusChatGridVisibility));
}
}
private Contact _CurrentContact;
public Contact CurrentContact
@@ -114,7 +128,6 @@ namespace ChatController
}
}
// ToDo: Hier die ContactDepenencyObject-Klasse benutzen wie im Kalender des BeWoPlaners!
public ObservableSortCollection<ContactDependencyObject> ContactList
{
get => _ContactList ?? (_ContactList = new ObservableSortCollection<ContactDependencyObject>());
@@ -137,12 +150,7 @@ namespace ChatController
return Visibility.Collapsed;
}
if(false == (Chat?.IsInBroadcastMode ?? false) && !(_CurrentContact is null))
{
return _CurrentContact.IsChatMessageInputGridVisible ? Visibility.Visible : Visibility.Collapsed;
}
return Chat?.IsInBroadcastMode ?? false ? Visibility.Visible : Visibility.Collapsed;
return false == (Chat?.IsInBroadcastMode ?? false) && !(_CurrentContact is null) ? _CurrentContact.IsChatMessageInputGridVisible ? Visibility.Visible : Visibility.Collapsed : Chat?.IsInBroadcastMode ?? false ? Visibility.Visible : Visibility.Collapsed;
}
}
@@ -165,6 +173,8 @@ namespace ChatController
InitializeComponent();
_ThreadExceptionImageSource = new BitmapImage(new Uri("pack://application:,,,/ChatController;component/Ressourcen/warning-exclamation-mark.png", UriKind.Absolute));
BroadcastButtonImageSource = new BitmapImage(new Uri("pack://application:,,,/ChatController;component/Ressourcen/tasks-solid.png", UriKind.Absolute));
InvertedBroadcastButtonImageSource = new BitmapImage(new Uri("pack://application:,,,/ChatController;component/Ressourcen/tasks-solid-inverted.png", UriKind.Absolute));
_ChatMessages = new ObservableCollection<ChatMessage>();
ChatMessages = CollectionViewSource.GetDefaultView(_ChatMessages) as ListCollectionView;
@@ -175,6 +185,42 @@ namespace ChatController
}
DataContext = this;
ProgressOverlayVisibility = Visibility.Collapsed;
StartWaitingImmediately();
var deleteImagesTask = new Task(() =>
{
try
{
var files = Directory.GetFiles(Path.GetTempPath(), "*_tmp_img_owch.*", SearchOption.TopDirectoryOnly);
foreach(var file in files)
{
if(File.Exists(file))
{
try
{
File.Delete(file);
}
catch(IOException)
{
}
}
}
}
finally
{
this.Dispatch(() =>
{
EndWaiting();
});
}
});
deleteImagesTask.Start();
}
private void ContainingWindowOnDeactivated(object sender, EventArgs e)
@@ -251,7 +297,7 @@ namespace ChatController
var contact = _ContactList.FirstOrDefault(a => a.Contact.GroupId == pGroupId);
if (contact != null)
if (!(contact is null))
{
notificationIcon = Utils.ImageSourceToIcon(contact.Contact.Image);
}
@@ -262,7 +308,7 @@ namespace ChatController
{
DisposeAndRemoveNotification((NotifyIcon)sender, pGroupId);
if(_ContainingWindow == null)
if(_ContainingWindow is null)
{
return;
}
@@ -275,7 +321,7 @@ namespace ChatController
_ContainingWindow.Activate();
var selectedContact = _ContactList?.FirstOrDefault(f => f?.Contact.GroupId == pGroupId);
if(selectedContact != null)
if(!(selectedContact is null))
{
SelectContact(selectedContact.Contact);
}
@@ -315,14 +361,6 @@ namespace ChatController
Application.DoEvents();
}
public void ResetStyle()
{
EmojiButton.Style = null;
MediaButton.Style = null;
ReloadGruppen.Visibility = Visibility.Visible;
_IsDesktopVersion = false;
}
private void CurrentContactImage_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if(e.ClickCount == 2)
@@ -344,33 +382,35 @@ namespace ChatController
}
}
private void SelectContact(Contact pContact)
private void SelectContact(Contact contact)
{
try
{
if (pContact is null)
if(contact is null)
{
return;
}
ChatMessageFileWrapper = null;
ShouldInterruptContactsThread = true;
StartWaitingImmediately();
_ScrollPrueferAktivieren = false;
if (pContact.HasUnreadMessages)
if(contact.HasUnreadMessages)
{
pContact.HasUnreadMessages = false;
contact.HasUnreadMessages = false;
Clientlist.Items.Refresh();
OnPropertyChanged(nameof(ContactList));
}
var currentContact = pContact;
pContact.IsNewMessage = false;
var currentContact = contact;
contact.IsNewMessage = false;
var shouldChangeIcon = _ContactList.Any(contact => contact.Contact.IsNewMessage);
var shouldChangeIcon = _ContactList.Any(contactDependencyObject => contactDependencyObject.Contact.IsNewMessage);
if(shouldChangeIcon)
{
ContainingWindow.Icon = Utils.ConvertIconToImageSource(Resource.ownchat_favicon);
@@ -378,9 +418,11 @@ namespace ChatController
CurrentContact = currentContact;
OnPropertyChanged(nameof(IsSendButtonEnabled));
foreach(ContactDependencyObject item in Clientlist.Items)
{
if(item.Contact.Equals(pContact))
if(item.Contact.Equals(contact))
{
Clientlist.SelectedItem = item;
}
@@ -436,7 +478,7 @@ namespace ChatController
{
var contextItems = ChatListBox?.ContextMenu?.Items;
if(contextItems == null)
if(contextItems is null)
{
return;
}
@@ -494,24 +536,24 @@ namespace ChatController
private void CopyOnClick(object sender, RoutedEventArgs routedEventArgs)
{
var chatMessages = string.Empty;
var textToCopy = string.Empty;
foreach (var items in ChatListBox.SelectedItems)
{
var item = (ChatMessage) items;
chatMessages += item.UserMessage + "\n";
textToCopy += item.UserMessage + Environment.NewLine;
}
if(!string.IsNullOrWhiteSpace(chatMessages))
if(!string.IsNullOrWhiteSpace(textToCopy))
{
Chat.Copy(chatMessages, 1);
Chat.Copy(textToCopy, 1);
}
}
private void Chat_OnContextMenuOpening(object sender, ContextMenuEventArgs e)
{
if(ChatListBox?.ContextMenu == null)
if(ChatListBox?.ContextMenu is null)
{
return;
}
@@ -520,12 +562,11 @@ namespace ChatController
{
if(chatMessages.Count > 0)
{
foreach(var items in chatMessages)
foreach(var chatMessage in chatMessages)
{
var item = (ChatMessage) items;
if(item?.PictureSource != null)
if(!(chatMessage?.PictureSource is null))
{
if(ChatListBox.ContextMenu != null)
if(!(ChatListBox.ContextMenu is null))
{
var contextItems = ChatListBox.ContextMenu.Items;
((MenuItem)contextItems[0]).Visibility = Visibility.Visible;
@@ -538,7 +579,7 @@ namespace ChatController
contextItemSpeichernUnter.Visibility = Visibility.Collapsed;
}
if(item.PictureSource == null && item.FilePath == null)
if(chatMessage?.PictureSource is null && chatMessage?.FilePath is null)
{
var contextItems = ChatListBox.ContextMenu.Items;
var contextItemSpeichernUnter = (MenuItem)contextItems[2];
@@ -563,19 +604,19 @@ namespace ChatController
//prüfe ob was in dem Speicher vorhanden ist //Einfügen
var dataObject = System.Windows.Forms.Clipboard.GetDataObject();
if(dataObject != null && dataObject.GetDataPresent(DataFormats.FileDrop))
if(!(dataObject is null) && dataObject.GetDataPresent(DataFormats.FileDrop))
{
var contextItems = ChatListBox.ContextMenu.Items;
var contextItemSpeichernUnter = (MenuItem) contextItems[1];
contextItemSpeichernUnter.Visibility = Visibility.Visible;
}
else if(dataObject != null && dataObject.GetDataPresent(DataFormats.Text))
else if(!(dataObject is null) && dataObject.GetDataPresent(DataFormats.Text))
{
var contextItems = ChatListBox.ContextMenu.Items;
var contextItemSpeichernUnter = (MenuItem) contextItems[1];
contextItemSpeichernUnter.Visibility = Visibility.Visible;
}
else if(dataObject != null && dataObject.GetDataPresent(DataFormats.Bitmap))
else if(!(dataObject is null) && dataObject.GetDataPresent(DataFormats.Bitmap))
{
var contextItems = ChatListBox.ContextMenu.Items;
var contextItemSpeichernUnter = (MenuItem) contextItems[1];
@@ -589,7 +630,7 @@ namespace ChatController
}
// Prüfe, ob Dokumentation erlaubt
if(CurrentContact.UserIdManage == null && ChatListBox.ContextMenu.Items.Count > 3)
if(CurrentContact.UserIdManage is null && ChatListBox.ContextMenu.Items.Count > 3)
{
var contextItems = ChatListBox.ContextMenu.Items;
var contextItemSpeichernUnter = (MenuItem)contextItems[3];
@@ -609,13 +650,19 @@ namespace ChatController
}
}
private async void MediaButton_OnClick(object sender, RoutedEventArgs e)
private void MediaButton_OnClick(object sender, RoutedEventArgs e)
{
if(CurrentContact != null)
if(!(CurrentContact is null))
{
var pathToOriginalImage = Chat.OpenFile();
if(pathToOriginalImage != null)
if(File.Exists(pathToOriginalImage))
{
StartWaitingImmediately("Skaliere Bild ...");
var scalingTask = new Task(() =>
{
try
{
var pathToScaledImage = FileUtils.ScaleImage(pathToOriginalImage, Path.GetExtension(pathToOriginalImage.ToUpperInvariant()), Chat.ChatDaten.MaxUploadSize);
@@ -623,27 +670,27 @@ namespace ChatController
if(isFileSizeTooLarge)
{
this.Dispatch(() =>
{
EndWaiting();
MessageBox.Show($"Die ausgewählte Datei ist zu groß. Die maximale Größe beträgt {Chat.ChatDaten.MaxUploadSize / 1000 / 1000} MB", "Senden nicht möglich", MessageBoxButton.OK, MessageBoxImage.Warning);
});
return;
}
if(File.Exists(pathToScaledImage))
{
_ChatMessages.AddRangeIfElementsNotIn(Chat.AddNewFile(pathToScaledImage, pathToOriginalImage, CurrentContact.GroupId, GetFirstMessage()));
ChatMessages.MoveCurrentToLast();
var currentChatMessage = ChatMessages.CurrentItem;
ChatListBox.ScrollIntoView(currentChatMessage);
await Chat.SendFileToContact(CurrentContact, pathToScaledImage, pathToOriginalImage, Chatbox.Text);
if (!string.IsNullOrWhiteSpace(pathToScaledImage) && !pathToScaledImage.Equals(pathToOriginalImage) && File.Exists(pathToScaledImage))
ChatMessageFileWrapper = new ChatMessageFileWrapper(pathToOriginalImage, pathToScaledImage, $"{Chat.ChatDaten.ServerUrl}/document.png");
}
}
finally
{
File.Delete(pathToScaledImage);
}
this.Dispatch(EndWaiting);
}
});
scalingTask.Start();
}
}
else
@@ -652,6 +699,64 @@ namespace ChatController
}
}
private async Task SendMessage()
{
if(CurrentContact is null || (string.IsNullOrEmpty(Chatbox.Text) && string.IsNullOrWhiteSpace(ChatMessageFileWrapper?.ScaledFilePath)))
{
return;
}
var isFileInMessage = !(ChatMessageFileWrapper is null) && File.Exists(ChatMessageFileWrapper.ScaledFilePath);
var messageText = Chatbox.Text;
var newMessages = isFileInMessage ?
Chat.AddNewFile(ChatMessageFileWrapper.ScaledFilePath, ChatMessageFileWrapper.OriginalFilePath, CurrentContact.GroupId, GetFirstMessage(), messageText) :
Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId, GetFirstMessage());
_ChatMessages.AddRangeIfElementsNotIn(newMessages);
OnPropertyChanged(nameof(ChatMessages));
ChatMessages.MoveCurrentToLast();
ChatListBox.ScrollIntoView(ChatMessages.CurrentItem);
WpfUtils.ScrollToBottomOfListBox(ChatListBox);
if(isFileInMessage)
{
await Chat.SendFileToContact(CurrentContact, ChatMessageFileWrapper.ScaledFilePath, ChatMessageFileWrapper.OriginalFilePath, Chatbox.Text);
}
else
{
await Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId);
}
ChatMessageFileWrapper = null;
Chatbox.Text = string.Empty;
//DoSynchro();
}
public Visibility ChatListBoxVisibility => (Chat?.IsInBroadcastMode ?? false) || !(ChatMessageFileWrapper is null) ? Visibility.Collapsed : Visibility.Visible;
public Visibility FilePreviewGridVisibility => string.IsNullOrWhiteSpace(ChatMessageFileWrapper?.OriginalFilePath) ? Visibility.Collapsed : Visibility.Visible;
private ChatMessageFileWrapper _ChatMessageFileWrapper;
public ChatMessageFileWrapper ChatMessageFileWrapper
{
get => _ChatMessageFileWrapper;
set
{
_ChatMessageFileWrapper = value;
OnPropertyChanged(nameof(ChatMessageFileWrapper));
OnPropertyChanged(nameof(IsSendButtonEnabled));
OnPropertyChanged(nameof(FilePreviewGridVisibility));
OnPropertyChanged(nameof(ChatListBoxVisibility));
}
}
private async void SendButton_OnClick(object sender, RoutedEventArgs e)
{
if(Chat.IsInBroadcastMode)
@@ -660,24 +765,7 @@ namespace ChatController
return;
}
if(CurrentContact != null && !string.IsNullOrEmpty(Chatbox.Text))
{
var messages2Add = Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId, GetFirstMessage());
_ChatMessages.AddRangeIfElementsNotIn(messages2Add);
OnPropertyChanged(nameof(ChatMessages));
ChatMessages.MoveCurrentToLast();
ChatListBox.ScrollIntoView(ChatMessages.CurrentItem);
WpfUtils.ScrollToBottomOfListBox(ChatListBox);
await Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId);
Chatbox.Text = string.Empty;
DoSynchro();
}
await SendMessage();
}
private void Chatbox_OnGotFocus(object sender, RoutedEventArgs e)
@@ -799,16 +887,11 @@ namespace ChatController
private void InitGlobalListeningThread()
{
GlobalListeningThreadtimer = new Timer();
GlobalListeningThreadtimer.Tick += GlobalListeningThreadTimerTickEvent;
GlobalListeningThreadtimer.Tick += (s, e) => { ListenGloballyForMessages(); };
GlobalListeningThreadtimer.Interval = 10000;
GlobalListeningThreadtimer.Start();
}
private void GlobalListeningThreadTimerTickEvent(object sender, EventArgs e)
{
ListenGloballyForMessages();
}
private void ListenGloballyForMessages()
{
Chat.GetNumberOfAllNewMessagesAsync(newMessagesCount =>
@@ -821,17 +904,17 @@ namespace ChatController
this.Dispatch(() =>
{
foreach (var contact in _ContactList)
foreach (var contactDependencyObject in _ContactList)
{
foreach (var newContact in updatedContacts)
{
if (contact.Contact.GroupId == newContact.GroupId)
if (contactDependencyObject.Contact.GroupId == newContact.GroupId)
{
// ReceivedMessage kann null sein!
if (contact.Contact.ReceivedMessage != null && !contact.Contact.ReceivedMessage.Id.Equals(newContact.ReceivedMessage?.Id))
if (!(contactDependencyObject.Contact.ReceivedMessage is null) && !contactDependencyObject.Contact.ReceivedMessage.Id.Equals(newContact.ReceivedMessage?.Id))
{
contact.Contact.ReceivedMessage = newContact.ReceivedMessage;
contact.Contact.TimeStamp = newContact.TimeStamp;
contactDependencyObject.Contact.ReceivedMessage = newContact.ReceivedMessage;
contactDependencyObject.Contact.TimeStamp = newContact.TimeStamp;
Contact selectedContact = null;
@@ -843,14 +926,14 @@ namespace ChatController
// Angemeldeter Benutzer
var userOid = Chat.ChatDaten.LoggedInUser.Response.User.Oid;
var senderId = contact.Contact.ReceivedMessage?.UserId;
var senderId = contactDependencyObject.Contact.ReceivedMessage?.UserId;
var receiverId = userOid;
var receiverGroupId = newContact.GroupId;
var selectedGroupId = selectedContact?.GroupId;
if (senderId != receiverId && (_IsInBackground || receiverGroupId != selectedGroupId))
{
if (ContainingWindow != null)
if (!(ContainingWindow is null))
{
ContainingWindow.Icon = Utils.ConvertIconToImageSource(Resource.oC_favico_NewMessage);
}
@@ -859,26 +942,26 @@ namespace ChatController
}
// Wenn der momentan ausgewählte Kontakt der aktuelle Kontakt in der Schleife ist, werden die Nachrichten nicht als ungelesen angezeigt, sonst schon.
if (CurrentContact != null && newContact.GroupId == CurrentContact.GroupId)
if (!(CurrentContact is null) && newContact.GroupId == CurrentContact.GroupId)
{
contact.Contact.HasUnreadMessages = false;
contactDependencyObject.Contact.HasUnreadMessages = false;
}
else
{
contact.Contact.HasUnreadMessages = true;
contact.Contact.IsNewMessage = true;
contactDependencyObject.Contact.HasUnreadMessages = true;
contactDependencyObject.Contact.IsNewMessage = true;
}
}
}
}
if (!updatedContacts.Contains(contact.Contact))
if (!updatedContacts.Contains(contactDependencyObject.Contact))
{
_ContactList.ToList().Remove(contact);
_ContactList.ToList().Remove(contactDependencyObject);
}
}
Clientlist.Items.Refresh();
ContactList.Sort((x, y) => DateTime.Compare(y.Contact.TimeStamp, x.Contact.TimeStamp));
OnPropertyChanged(nameof(ChatMessages));
OnPropertyChanged(nameof(ContactList));
});
@@ -961,6 +1044,7 @@ namespace ChatController
{
var bitmapImage = new BitmapImage(uri);
bitmapImage.Freeze();
Chat.ShowPictureWindow(bitmapImage, "Test");
return;
@@ -977,11 +1061,11 @@ namespace ChatController
});
});
}
else if(selectedMessage.FilePath != null)
else if(!(selectedMessage.FilePath is null))
{
StartWaitingImmediately();
LoadDocumentAsync(selectedMessage.FilePath.ToString(), Path.GetFileName(selectedMessage.FilePath.ToString()), EndWaiting);
LoadDocumentAsync(selectedMessage.FilePath, Path.GetFileName(selectedMessage.FilePath), EndWaiting);
}
}
}
@@ -1029,14 +1113,14 @@ namespace ChatController
public void StartWaiting()
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)StartWaitingImmediately);
Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action<string>) StartWaitingImmediately);
}
public void StartWaitingImmediately()
public void StartWaitingImmediately(string dialogText = null)
{
if (_WaitLayer == null)
if (_WaitLayer is null)
{
_WaitLayer = new ChatControlWaitLayer();
_WaitLayer = new ChatControlWaitLayer(dialogText);
Grid.SetRowSpan(_WaitLayer, 3);
RootGrid.Children.Add(_WaitLayer);
Panel.SetZIndex(_WaitLayer, int.MaxValue);
@@ -1050,7 +1134,7 @@ namespace ChatController
DispatcherPriority.Background,
(Action) delegate
{
if(_WaitLayer != null)
if(!(_WaitLayer is null))
{
RootGrid.Children.Remove(_WaitLayer);
_WaitLayer = null;
@@ -1076,12 +1160,23 @@ namespace ChatController
this.Dispatch(() =>
{
ContactList = new ObservableSortCollection<ContactDependencyObject>();
foreach(var contact in Chat.UpdateContacts(data))// <- dauert eine Sekunde!
foreach(var contact in Chat.UpdateContacts(data))
{
ContactList.Add(new ContactDependencyObject(contact));
}
ContactList.Sort((x, y) => DateTime.Compare(y.Contact.TimeStamp, x.Contact.TimeStamp));
if(!(CurrentContact is null))
{
var selectedElement = ContactList.FirstOrDefault(f => f.Contact.GroupId == CurrentContact.GroupId);
if(!(selectedElement is null))
{
Clientlist.SelectedItem = selectedElement;
}
}
OnPropertyChanged(nameof(ContactList));
ReadNewSyncFile();
@@ -1114,7 +1209,7 @@ namespace ChatController
{
Encoding enc = new UTF8Encoding();
foreach (var contact in _ContactList.ToList().Where(contact => contact.Contact.ReceivedMessage != null))
foreach (var contact in _ContactList.ToList().Where(contact => !(contact.Contact.ReceivedMessage is null)))
{
var text = contact.Contact.GroupId + ";" + contact.Contact.TimeStamp.ToUniversalTime() + ";" + contact.Contact.IsNewMessage + ";";
var bytes = enc.GetBytes(text);
@@ -1144,7 +1239,7 @@ namespace ChatController
_GroupId2DateTime.Clear();
while ((line = streamReader.ReadLine()) != null)
while (!((line = streamReader.ReadLine()) is null))
{
var encodedTextBytes = Convert.FromBase64String(line);
var plainText = Encoding.UTF8.GetString(encodedTextBytes);
@@ -1200,15 +1295,15 @@ namespace ChatController
// Wird im BeWoPlaner benutzt
public void ResetNumberOfUnreadMessages(Dictionary<long, DateTime> pGroupId2DateTime)
{
if(pGroupId2DateTime != null)
if(!(pGroupId2DateTime is null))
{
foreach(var contact in _ContactList)
foreach(var contactDependencyObject in _ContactList)
{
foreach(var groupId2DateTime in pGroupId2DateTime)
{
if(contact.Contact.GroupId == groupId2DateTime.Key)
if(contactDependencyObject.Contact.GroupId == groupId2DateTime.Key)
{
contact.Contact.HasUnreadMessages = false;
contactDependencyObject.Contact.HasUnreadMessages = false;
}
}
}
@@ -1226,7 +1321,7 @@ namespace ChatController
// Wird im BeWoPlaner benutzt
public Contact GetCurrentContactWithUserIdManage()
{
return CurrentContact?.UserIdManage != null ? CurrentContact : null;
return !(CurrentContact?.UserIdManage is null) ? CurrentContact : null;
}
// Wird im BeWoPlaner benutzt
@@ -1303,17 +1398,38 @@ namespace ChatController
}
#region Broadcast
#region Stapelnachricht
public bool IsSendButtonEnabled => !string.IsNullOrEmpty(Chatbox.Text);
public ImageSource BroadcastButtonImageSource { get; }
public ImageSource InvertedBroadcastButtonImageSource { get; }
private Visibility _ProgressOverlayVisibility;
public Visibility ProgressOverlayVisibility
{
get => _ProgressOverlayVisibility;
set
{
_ProgressOverlayVisibility = value;
OnPropertyChanged(nameof(ProgressOverlayVisibility));
OnPropertyChanged(nameof(NormalViewVisibility));
OnPropertyChanged(nameof(StapelmodusChatGridVisibility));
OnPropertyChanged(nameof(ChatListBoxVisibility));
}
}
public Visibility NormalViewVisibility => ProgressOverlayVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
public Visibility StapelmodusChatGridVisibility => (Chat?.IsInBroadcastMode ?? false) && ProgressOverlayVisibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
public bool IsSendButtonEnabled => (!string.IsNullOrEmpty(Chatbox.Text) || File.Exists(ChatMessageFileWrapper?.ScaledFilePath)) && !(CurrentContact is null);
public bool IsBroadcastButtonEnabled
{
get
{
var isInBroadcastMode = Chat.IsInBroadcastMode;
var isInBroadcastMode = Chat?.IsInBroadcastMode ?? false;
var hasSelectedContacts = GetSelectedContacts().Any();
var hasTextOrFile = !string.IsNullOrEmpty(Chatbox.Text) || !(BroadcastMessage?.BroadcastMessageImageSource is null);
var hasTextOrFile = !string.IsNullOrEmpty(Chatbox.Text) || File.Exists(BroadcastMessageFileWrapper?.ScaledFilePath);
return isInBroadcastMode && hasSelectedContacts && hasTextOrFile;
}
@@ -1323,7 +1439,7 @@ namespace ChatController
private CancellationTokenSource _CancellationTokenSource;
private string _DefaultBroadcastInfoText = "Dies ist eine Nachricht, die als Broadcast an alle ausgewählten Kontakte geschickt wird.";
private string _DefaultBroadcastInfoText = "Sie befinden Sich im Stapel-Modus. In diesem Modus können Sie eine Nachricht in einem Schritt an mehrere Empfänger & Gruppen senden. Bitte setzen Sie dazu in der Kontaktliste bei den gewünschten Empfängern & Gruppen ein Häkchen und schreiben Sie Ihre Nachricht wie gewohnt. Wenn Sie auf senden klicken, wird die Nachricht an alle ausgewählten Empfänger & Gruppen gesendet.";
private string _BroadcastInfoText;
public string BroadcastInfoText
@@ -1347,21 +1463,23 @@ namespace ChatController
}
}
private BroadcastMessage _BroadcastMessage;
public BroadcastMessage BroadcastMessage
public Visibility RemoveFileFromBroadcastMessageVisibility => BroadcastMessageFileWrapper is null ? Visibility.Collapsed : Visibility;
private ChatMessageFileWrapper _BroadcastMessageFileWrapper;
public ChatMessageFileWrapper BroadcastMessageFileWrapper
{
get => _BroadcastMessage;
get => _BroadcastMessageFileWrapper;
set
{
_BroadcastMessage = value;
_BroadcastMessageFileWrapper = value;
OnPropertyChanged(nameof(BroadcastMessage));
OnPropertyChanged(nameof(BroadcastMessageFileWrapper));
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
OnPropertyChanged(nameof(RemoveFileFromBroadcastMessageVisibility));
}
}
private void BroadcastButton_OnClick(object sender, RoutedEventArgs e)
private void BroadcastToggleButton_OnClick(object sender, RoutedEventArgs e)
{
Chat.IsInBroadcastMode = !Chat.IsInBroadcastMode;
@@ -1374,66 +1492,84 @@ namespace ChatController
_CancellationTokenSource = new CancellationTokenSource();
_PreviousContact = CurrentContact;
CurrentContact = null;
ToggleButtonImage.Source = InvertedBroadcastButtonImageSource;
}
else
{
CloseBroadcastMode();
}
OnPropertyChanged(nameof(StapelmodusChatGridVisibility));
OnPropertyChanged(nameof(ChatListBoxVisibility));
OnPropertyChanged(nameof(IsSendButtonEnabled));
OnPropertyChanged(nameof(ChatMessageInputGridVisibility));
OnPropertyChanged(nameof(BroadcastMessage));
}
private void AbortBroadcastButton_OnClick(object sender, RoutedEventArgs e)
{
CloseBroadcastMode();
OnPropertyChanged(nameof(BroadcastMessageFileWrapper));
}
private async void SendBroadcastMessage()
{
var selectedContacts = GetSelectedContacts();
if (selectedContacts.Count == 0 || string.IsNullOrEmpty(Chatbox.Text) && BroadcastMessage.BroadcastMessageImageSource is null)
if(selectedContacts.Count == 0 || string.IsNullOrEmpty(Chatbox.Text) && BroadcastMessageFileWrapper.ChatMessageImageSource is null)
{
return;
}
var result = new OwnChatMessageBox("JA", "ABBRECHEN", $"Sind Sie sicher? Ihre Nachricht wird an {selectedContacts.Count} Empfänger & Gruppen verschickt!", "Stapelnachricht") { Owner = ContainingWindow }.ShowDialog();
if(result != true)
{
return;
}
var wasCompleted = false;
var progress = new Progress<BroadcastProgressReportModel>();
progress.ProgressChanged += ReportProgress;
try
{
await SendBroadcast(progress, _CancellationTokenSource.Token);
ProgressOverlayVisibility = Visibility.Visible;
wasCompleted = await SendBroadcast(progress, _CancellationTokenSource.Token);
}
catch(OperationCanceledException)
{
BroadcastInfoText = "Der Broadcast wurde abgebrochen.";
}
finally
{
ProgressOverlayVisibility = Visibility.Collapsed;
}
DoSynchro();
if(wasCompleted)
{
new OwnChatMessageBox(null, "OK", $"Die Nachricht wurde erfolgreich an {selectedContacts.Count} Empfänger & Gruppen versandt.", "Stapelnachricht") { Owner = ContainingWindow }.ShowDialog();
}
CloseBroadcastMode();
}
private async Task SendBroadcast(IProgress<BroadcastProgressReportModel> progress, CancellationToken cancellationToken)
private async Task<bool> SendBroadcast(IProgress<BroadcastProgressReportModel> progress, CancellationToken cancellationToken)
{
var count = 0;
var report = new BroadcastProgressReportModel();
var selectedContacts = GetSelectedContacts();
foreach (var contact in selectedContacts.Where(selectedContact => selectedContact.IsChatMessageInputGridVisible))
foreach(var contactDependencyObject in selectedContacts.Where(selectedContact => selectedContact.Contact.IsChatMessageInputGridVisible))
{
if(BroadcastMessage is null)
if(BroadcastMessageFileWrapper is null)
{
await Chat.SendMessage(Chatbox.Text, contact.GroupId);
await Chat.SendMessage(Chatbox.Text, contactDependencyObject.Contact.GroupId);
}
else
{
await Chat.SendFileToContact(contact, BroadcastMessage.ScaledFilePath, BroadcastMessage.OriginalFilePath, Chatbox.Text);
await Chat.SendFileToContact(contactDependencyObject.Contact, BroadcastMessageFileWrapper.ScaledFilePath, BroadcastMessageFileWrapper.OriginalFilePath, Chatbox.Text);
}
contactDependencyObject.SetValue(ListItemHelper.IsCheckedProperty, false);
cancellationToken.ThrowIfCancellationRequested();
count++;
@@ -1441,6 +1577,8 @@ namespace ChatController
progress.Report(report);
}
return count == selectedContacts.Count;
}
private void ReportProgress(object sender, BroadcastProgressReportModel e)
@@ -1472,7 +1610,7 @@ namespace ChatController
private void CancelBroadcastButton_OnClick(object sender, RoutedEventArgs e)
{
_CancellationTokenSource?.Cancel();
BroadcastMessage = null;
BroadcastMessageFileWrapper = null;
Chatbox.Text = string.Empty;
}
@@ -1483,6 +1621,12 @@ namespace ChatController
var originalFilePath = Chat.OpenFile();
if(File.Exists(originalFilePath))
{
StartWaitingImmediately("Skaliere Bild ...");
var scalingTask = new Task(() =>
{
try
{
var scaledImagePath = FileUtils.ScaleImage(originalFilePath, Path.GetExtension(originalFilePath.ToUpperInvariant()), Chat.ChatDaten.MaxUploadSize);
@@ -1496,11 +1640,16 @@ namespace ChatController
if(File.Exists(scaledImagePath))
{
if (BroadcastMessage is null)
BroadcastMessageFileWrapper = new ChatMessageFileWrapper(originalFilePath, scaledImagePath, $"{Chat.ChatDaten.ServerUrl}/document.png");
}
}
finally
{
BroadcastMessage = new BroadcastMessage(originalFilePath, scaledImagePath);
}
this.Dispatch(EndWaiting);
}
});
scalingTask.Start();
}
}
}
@@ -1509,24 +1658,28 @@ namespace ChatController
{
Chatbox.Text = string.Empty;
if(!(_PreviousContact is null))
{
SelectContact(_PreviousContact);
}
BroadcastToggleButton.IsChecked = false;
Chat.IsInBroadcastMode = false;
_CancellationTokenSource = null;
BroadcastMessage = null;
BroadcastMessageFileWrapper = null;
BroadcastProgressValue = 0;
ProgressOverlayVisibility = Visibility.Collapsed;
DeselectAllContacts();
OnPropertyChanged(nameof(IsSendButtonEnabled));
OnPropertyChanged(nameof(ChatMessageInputGridVisibility));
OnPropertyChanged(nameof(BroadcastMessage));
OnPropertyChanged(nameof(BroadcastMessageFileWrapper));
Chat.IsInBroadcastMode = false;
ToggleButtonImage.Source = BroadcastButtonImageSource;
OnPropertyChanged(nameof(StapelmodusChatGridVisibility));
if(!(_PreviousContact is null))
{
SelectContact(_PreviousContact);
}
}
#endregion
private void ContactCheckBox_OnClick(object sender, RoutedEventArgs e)
{
@@ -1543,18 +1696,33 @@ namespace ChatController
OnPropertyChanged(nameof(ContactList));
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
SelectAllContactsCheckBox.IsChecked = GetSelectedContacts().Count == ContactList.Where(contactDependencyObject => contactDependencyObject.Contact.IsChatMessageInputGridVisible).ToList().Count;
bool? newValue = null;
var selectedContacts = GetSelectedContacts();
var allSelectableContacts = ContactList.Where(contactDependencyObject => contactDependencyObject.Contact.IsChatMessageInputGridVisible).ToList();
if(selectedContacts.Count == allSelectableContacts.Count)
{
newValue = true;
}
private List<Contact> GetSelectedContacts()
if(selectedContacts.Count == 0)
{
var result = new List<Contact>();
newValue = false;
}
SelectAllContactsCheckBox.IsChecked = newValue;
}
private List<ContactDependencyObject> GetSelectedContacts()
{
var result = new List<ContactDependencyObject>();
foreach(var contactDependencyObject in ContactList.Where(contactDependencyObject => contactDependencyObject.Contact.IsChatMessageInputGridVisible))
{
if(contactDependencyObject.GetValue(ListItemHelper.IsCheckedProperty) is bool isChecked && isChecked)
{
result.AddIfNotIn(contactDependencyObject.Contact);
result.AddIfNotIn(contactDependencyObject);
}
}
@@ -1568,5 +1736,17 @@ namespace ChatController
contactDependencyObject.SetValue(ListItemHelper.IsCheckedProperty, false);
}
}
private void RemoveBroadcastFileAttachmentButton_Click(object sender, RoutedEventArgs e)
{
BroadcastMessageFileWrapper = null;
}
#endregion
private void RemoveFileAttachmentButton_Click(object sender, RoutedEventArgs e)
{
ChatMessageFileWrapper = null;
}
}
}

View File

@@ -16,6 +16,11 @@ namespace ChatController.Converter
return boolValue ? Visibility.Visible : Visibility.Collapsed;
}
if(parameter is string reverseHiddenString && Equals(reverseHiddenString, "reverse_hidden"))
{
return boolValue ? Visibility.Visible : Visibility.Hidden;
}
return boolValue ? Visibility.Collapsed : Visibility.Visible;
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace ChatController.Converter
{
public class OwnChatNullVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value is null ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -9,7 +9,7 @@ namespace ChatController.Converter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if(values != null && values.Length == 2 && values[0] is bool isMyMessage && values[1] is bool isGroupChat)
if(!(values is null) && values.Length == 2 && values[0] is bool isMyMessage && values[1] is bool isGroupChat)
{
if(parameter is string test && test == "reverse")
{

View File

@@ -17,7 +17,7 @@ namespace ChatController.Core
public static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if(e.NewValue == null)
if(e.NewValue is null)
{
return;
}

View File

@@ -10,6 +10,38 @@ namespace ChatController.Core
private static readonly object _Lock = new object();
private ImageSource _DocumentThumbnail;
public ImageSource DocumentThumbnail
{
get => _DocumentThumbnail;
set
{
lock(_Lock)
{
if(!(value is null) && _DocumentThumbnail is null)
{
_DocumentThumbnail = value;
}
}
}
}
private ImageSource _ImagePlaceholder;
public ImageSource ImagePlaceholder
{
get => _ImagePlaceholder;
set
{
lock(_Lock)
{
if(!(value is null) && _ImagePlaceholder is null)
{
_ImagePlaceholder = value;
}
}
}
}
// Key-> "group-127" oder "user-938"
private Dictionary<string, ImageSourceCacheStorage> _ImageSourceCache = new Dictionary<string, ImageSourceCacheStorage>();
@@ -41,7 +73,7 @@ namespace ChatController.Core
{
lock(_Lock)
{
if(key == null || _ImageSourceCache == null || !_ImageSourceCache.ContainsKey(key))
if(key is null || _ImageSourceCache is null || !_ImageSourceCache.ContainsKey(key))
{
return null;
}
@@ -56,7 +88,7 @@ namespace ChatController.Core
{
lock(_Lock)
{
if(_ImageSourceCache == null)
if(_ImageSourceCache is null)
{
_ImageSourceCache = new Dictionary<string, ImageSourceCacheStorage>();
}
@@ -158,7 +190,7 @@ namespace ChatController.Core
public void SetCachedProfilePicture(ImageSource avatarImageSource, string profilePicturePath)
{
if(avatarImageSource != null && !string.IsNullOrWhiteSpace(profilePicturePath))
if(!(avatarImageSource is null) && !string.IsNullOrWhiteSpace(profilePicturePath))
{
ProfilePicturePath = profilePicturePath;
_ProfilePicture = new ImageSourceCacheObject(avatarImageSource, CacheCategory.ProfilePicture);
@@ -186,7 +218,7 @@ namespace ChatController.Core
public void AddImageSourceToCachedObjects(ImageSource imageSource, CacheCategory cacheCategory, string name)
{
if(CachedObjects == null)
if(CachedObjects is null)
{
CachedObjects = new Dictionary<CacheCategory, Dictionary<string, ImageSourceCacheObject>>();
}

View File

@@ -85,7 +85,7 @@ namespace ChatController.Data
using (var dataStream = response.GetResponseStream())
{
if(dataStream == null)
if(dataStream is null)
{
return serverResponse;
}

View File

@@ -4,6 +4,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
@@ -76,7 +77,7 @@ namespace ChatController.HauptKlassen
{
try
{
if(certificate == null || chain == null)
if(certificate is null || chain is null)
{
return false;
}
@@ -224,7 +225,7 @@ namespace ChatController.HauptKlassen
var span = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var timespan = Convert.ToInt64(span.TotalSeconds);
if (_UserMessages != null && _UserMessages.Response.Messages.Length > 0)
if (!(_UserMessages is null) && _UserMessages.Response.Messages.Length > 0)
{
timespan = _UserMessages.Response.Messages.First().Created_At;
}
@@ -354,9 +355,12 @@ namespace ChatController.HauptKlassen
var time = DateTime.Now;
var chatMessage = new ChatMessage(pGroupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, pMessage, time, true, 0, null, null, null, null, null, ChatMessageType.Message, ChatDaten.LoggedInUser.Response.User.Oid);
result.Add(chatMessage);
return AddSeparators(result);
result = AddSeparators(new List<ChatMessage> {previousMessage, chatMessage});
result.Remove(previousMessage);
return result;
}
catch (Exception exception)
{
@@ -366,95 +370,6 @@ namespace ChatController.HauptKlassen
return result;
}
// ToDo: Funktioniert nicht mit der Version von RestSharp, die mit .NET Version 4.5 kompatibel ist
public void SendMessageAsync(string message, long groupId)
{
try
{
var url = ChatDaten.ServerUrl + Constants.SendMessageUrl;
var requestBody = $"{HttpUtility.UrlEncode("groupid")}={HttpUtility.UrlEncode(groupId.ToString())}&{HttpUtility.UrlEncode("text")}={HttpUtility.UrlEncode(message)}";
var client = new RestClient(url);
var request = new RestRequest(Method.POST);
request.AddHeader(Constants.ContentTypeKey, Constants.MultipartContentTypeValue);
request.AddParameter(Constants.Token, ChatDaten.AuthToken);
request.AddParameter(Constants.CustomerId, ChatDaten.Kundennummer);
request.AddParameter(Constants.MultipartContentTypeValue, requestBody, ParameterType.RequestBody);
client.PostAsync(request, (response, handle) =>
{
});
/*
*
multiPartContent.Add(new StringContent(groupId.ToString()), "groupid");
multiPartContent.Add(new StringContent(message), "text");
//wegen Kontent nachschauen
httpRequest.Content = multiPartContent;
httpRequest.Headers.Add("Token", ChatDaten.AuthToken);
httpRequest.Headers.Add("CustomerID", ChatDaten.Kundennummer);
---------------------------------------------------------------------------------------------------------------------------------------------------
var url = _BaseUrl + Constants.LoginWithChatCodeUrl;
var requestBody = $"{HttpUtility.UrlEncode("username")}={HttpUtility.UrlEncode(_UserName)}&{HttpUtility.UrlEncode("password")}={HttpUtility.UrlEncode(_Password)}&{HttpUtility.UrlEncode("chatcode")}={HttpUtility.UrlEncode(_ChatCode)}";
var client = new RestClient(url);
var request = new RestRequest(Method.POST);
request.AddHeader(Constants.ContentTypeKey, Constants.FormUrlEncodedContentTypeValue);
request.AddParameter(Constants.CustomerId, _Tenant, ParameterType.HttpHeader);
request.AddParameter(Constants.FormUrlEncodedContentTypeValue, requestBody, ParameterType.RequestBody);
client.PostAsync(request, (response, handle) =>
{
Debug.WriteLine(response.Content);
var connectionData = JsonConvert.DeserializeObject<UserDaten>(response.Content);
if (connectionData.Success)
{
_AuthToken = connectionData.Response.User.Token;
_UserId = connectionData.Response.User.Oid;
Utils.AuthToken = _AuthToken;
Utils.Tenant = _Tenant;
_LoggedInUser = connectionData;
callback?.Invoke(true);
}
else
{
var errorMessage = string.Empty;
if (connectionData.Error?.ChatCodeFailed != null)
{
errorMessage = $"Fehler: {connectionData.Error.ChatCodeFailed[0]}\nBitte überprüfen Sie die Anmeldeinformationen.";
}
else if (connectionData.Error?.LoginFailed != null)
{
errorMessage = $"Fehler: {connectionData.Error.LoginFailed[0]}\nBitte überprüfen Sie die Anmeldeinformationen.";
}
if (!string.IsNullOrWhiteSpace(errorMessage))
{
exceptionCallback?.Invoke(errorMessage);
}
}
});
*/
}
catch(Exception exception)
{
MessageBox.Show(exception.Message, "Fehler", MessageBoxButton.OK);
}
}
public async Task SendMessage(string message, long groupId)
{
try
@@ -474,7 +389,7 @@ namespace ChatController.HauptKlassen
httpRequest.Headers.Add("CustomerID", ChatDaten.Kundennummer);
var httpClient = new HttpClient();
await httpClient.SendAsync(httpRequest, CancellationToken.None).ConfigureAwait(false);
await httpClient.SendAsync(httpRequest, CancellationToken.None);
}
}
catch (Exception exception)
@@ -503,7 +418,7 @@ namespace ChatController.HauptKlassen
}
}
public List<ChatMessage> AddNewFile(string pathToScaledFile, string originalFilePath, long groupId, ChatMessage previousMessage)
public List<ChatMessage> AddNewFile(string pathToScaledFile, string originalFilePath, long groupId, ChatMessage previousMessage, string chatBoxText)
{
var result = new List<ChatMessage>();
@@ -514,14 +429,50 @@ namespace ChatController.HauptKlassen
return result;
}
var latestMessage = _UserMessages.Response.Messages.Last();
var messageId = 0;
var userName = ChatDaten.LoggedInUser.Response.User.UserName;
var sendTime = DateTime.Now;
var fileName = Path.GetFileName(pathToScaledFile);
var imageFile = GetImageFile(pathToScaledFile, out var fileSize);
var isImage = Constants.ImageFileExtensions.Contains(Path.GetExtension(pathToScaledFile).ToUpperInvariant());
var messageText = string.IsNullOrWhiteSpace(chatBoxText) ? fileName : chatBoxText;
var filePath = isImage ? null : pathToScaledFile;
var originalImage = isImage ? pathToScaledFile : null;
var imageName = isImage ? fileName : null;
var linkToThumbnail = isImage ? null : $"{ChatDaten.ServerUrl}/document.png";
var logo = isImage ? imageFile : null;
var chatMessageType = isImage ? ChatMessageType.Image : ChatMessageType.Document;
var senderId = ChatDaten.LoggedInUser.Response.User.Oid;
if (Constants.ImageFileExtensions.Contains(Path.GetExtension(pathToScaledFile).ToUpperInvariant()))
var chatMessage = new ChatMessage(groupId, messageId, userName, messageText, sendTime, true, fileSize, filePath, originalImage, imageName, linkToThumbnail, logo, chatMessageType, senderId);
result = AddSeparators(new List<ChatMessage> { previousMessage, chatMessage });
result.Remove(previousMessage);
return result;
}
catch(Exception exception)
{
if(!(exception is IOException))
{
ExceptionCallback?.Invoke(exception);
}
}
return result;
}
private static BitmapImage GetImageFile(string pathToScaledFile, out long fileSize)
{
if(!File.Exists(pathToScaledFile) || !Constants.ImageFileExtensions.Contains(Path.GetExtension(pathToScaledFile).ToUpperInvariant()))
{
fileSize = 0L;
return null;
}
byte[] file;
using (Stream reader = File.OpenRead(pathToScaledFile))
using(Stream reader = File.Open(pathToScaledFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
file = Utils.ReadFully(reader);
}
@@ -552,7 +503,6 @@ namespace ChatController.HauptKlassen
bitmap.Save(stream, ImageFormat.Jpeg);
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
@@ -560,30 +510,12 @@ namespace ChatController.HauptKlassen
bitmapImage.EndInit();
bitmapImage.Freeze();
var chatMessage = new ChatMessage(groupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, Path.GetFileName(pathToScaledFile), sendTime, true, memoryStream.Length, null, pathToScaledFile, Path.GetFileName(pathToScaledFile), null, bitmapImage, ChatMessageType.Image, ChatDaten.LoggedInUser.Response.User.Oid);
result.Add(chatMessage);
fileSize = memoryStream.Length;
return bitmapImage;
}
}
}
}
else
{
var linkToThumbnail = $"{ChatDaten.ServerUrl}/document.png";
var chatMessage = new ChatMessage(groupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, Path.GetFileName(pathToScaledFile), sendTime, true, 0, pathToScaledFile, null, null, linkToThumbnail, null, ChatMessageType.Document, ChatDaten.LoggedInUser.Response.User.Oid);
result.Add(chatMessage);
}
return AddSeparators(result);
}
catch (Exception exception)
{
ExceptionCallback?.Invoke(exception);
}
return result;
}
public List<ChatMessage> AddFileToMessage(byte[] file, string fileName, long groupId, ChatMessage previousMessage)
{
@@ -594,7 +526,7 @@ namespace ChatController.HauptKlassen
return result;
}
if(previousMessage != null)
if(!(previousMessage is null))
{
result.Add(previousMessage);
}
@@ -643,7 +575,6 @@ namespace ChatController.HauptKlassen
}
}
// WebRequest
private async Task SendFile(string pFile, Contact currentContact, string pOriginalFilePath, string message)
{
if(string.IsNullOrEmpty(pOriginalFilePath))
@@ -662,19 +593,14 @@ namespace ChatController.HauptKlassen
if(Constants.ImageFileExtensions.Contains(Path.GetExtension(fileName).ToUpperInvariant()))
{
fileName = fileName.Replace(".bmp", ".jpg");
}
await SendMediaMessage(fileName, currentContact.GroupId, mediaFile, message);
}
else
{
await SendMediaMessage(fileName, currentContact.GroupId, mediaFile, message);
}
await SendMediaMessage(fileName, currentContact.GroupId, mediaFile, message, pFile);
}
private HttpRequestMessage _HttpRequest;
// WebRequest
private async Task SendMediaMessage(string fileName, long groupId, byte[] mediaFile, string message)
private async Task SendMediaMessage(string fileName, long groupId, byte[] mediaFile, string message, string pathToTempFile)
{
try
{
@@ -701,14 +627,11 @@ namespace ChatController.HauptKlassen
_HttpRequest.Headers.Add(Constants.CustomerId, ChatDaten.Kundennummer);
var httpClient = new HttpClient();
var httpResponse = await httpClient.SendAsync(_HttpRequest, CancellationToken.None);//.ConfigureAwait(false);
var antwortResponse = await httpResponse.Content.ReadAsStringAsync();
await httpClient.SendAsync(_HttpRequest, HttpCompletionOption.ResponseContentRead);
}
}
catch (Exception exception)
catch(Exception)
{
ExceptionCallback?.Invoke(exception);
}
}
@@ -738,7 +661,7 @@ namespace ChatController.HauptKlassen
public void SaveFileAs(ChatMessage pChatMessage)
{
if (pChatMessage.PictureSource != null)
if (!(pChatMessage.PictureSource is null))
{
SaveAs(1, Path.GetFileName(pChatMessage.OriginalImage), DownloadMediaFile(pChatMessage.OriginalImage));
}
@@ -812,7 +735,7 @@ namespace ChatController.HauptKlassen
{
var dataObject = Clipboard.GetDataObject();
if(dataObject == null)
if(dataObject is null)
{
return;
}
@@ -823,11 +746,13 @@ namespace ChatController.HauptKlassen
{
if(dataObject.GetData(DataFormats.FileDrop) is string[] fileList)
{
if (File.Exists(fileList[0]))
{
var fileName = Path.GetFileName(fileList[0]);
var pathToFile = fileList[0];
var mediaFile = File.ReadAllBytes(fileList[0]);
if(File.Exists(pathToFile))
{
var fileName = Path.GetFileName(pathToFile);
var mediaFile = File.ReadAllBytes(pathToFile);
pChatMainControl.AddMessages(AddFileToMessage(mediaFile, fileName, pGroupOid, pChatMainControl.GetFirstMessage()));
@@ -836,7 +761,7 @@ namespace ChatController.HauptKlassen
pChatMainControl.ChatListBox.Items.MoveCurrentToLast();
pChatMainControl.ChatListBox.ScrollIntoView(pChatMainControl.ChatListBox.Items.CurrentItem);
await SendMediaMessage(fileName, pGroupOid, mediaFile, null);
await SendMediaMessage(fileName, pGroupOid, mediaFile, null, pathToFile);
}
}
}
@@ -875,7 +800,7 @@ namespace ChatController.HauptKlassen
pChatMainControl.ChatListBox.Items.MoveCurrentToLast();
pChatMainControl.ChatListBox.ScrollIntoView(pChatMainControl.ChatListBox.Items.CurrentItem);
await SendMediaMessage(imageName, pGroupOid, Utils.ImageToByteArray(image), null);
await SendMediaMessage(imageName, pGroupOid, Utils.ImageToByteArray(image), null, null);
}
else
{
@@ -970,7 +895,6 @@ namespace ChatController.HauptKlassen
grid.Children.Clear();
grid.Children.Add(image);
window.SizeToContent = SizeToContent.WidthAndHeight;
window.Content = grid;
window.Margin = new Thickness(0);
@@ -1033,7 +957,7 @@ namespace ChatController.HauptKlassen
{
_Contacts.Clear();
if(chatDaten?.Response != null)
if(!(chatDaten?.Response is null))
{
_Contacts.AddRange(GenerateContactsFromServerResponse(chatDaten.Response.Groups.ToArray()));
}
@@ -1057,7 +981,7 @@ namespace ChatController.HauptKlassen
var latestMessage = groupInput.LastMessage;
if(latestMessage?.Text != null)
if(!(latestMessage?.Text is null))
{
var timeStamp = DateTime.Parse(latestMessage.Timestamp.Date);
var clientZone = TimeZoneInfo.Local;
@@ -1095,7 +1019,7 @@ namespace ChatController.HauptKlassen
if(pShouldUpdateLastTimeStamp)
{
if(latestMessage?.Timestamp?.Date != null)
if(!(latestMessage?.Timestamp?.Date is null))
{
var unixTimeStamp = DateTime.Parse(latestMessage.Timestamp.Date).GetUnixTimeStamp();
@@ -1119,7 +1043,7 @@ namespace ChatController.HauptKlassen
var time = DateTime.Parse(message.Timestamp.Date);
var clientZone = TimeZoneInfo.Local;
var formattedTime = TimeZoneInfo.ConvertTimeFromUtc(time, clientZone);
var isLoggedInUsersMessage = ChatDaten.Userid != null && message.UserId == ChatDaten.Userid.Value;
var isLoggedInUsersMessage = !(ChatDaten.Userid is null) && message.UserId == ChatDaten.Userid.Value;
var messageText = message.Text ?? (string.IsNullOrEmpty(message.File) ? string.Empty : message.Original_Filename);
if(!string.IsNullOrEmpty(message.File))
@@ -1150,7 +1074,7 @@ namespace ChatController.HauptKlassen
var previousMessage = messagesWithoutSeparators.OrderBy(message => message.SendTime).FirstOrDefault();
foreach(var message in messagesWithoutSeparators.OrderBy(message => message.SendTime))
{
if(!message.Equals(previousMessage) && previousMessage != null)
if(!message.Equals(previousMessage) && !(previousMessage is null))
{
if(message.SendTime.Date != previousMessage.SendTime.Date)
{
@@ -1210,10 +1134,6 @@ namespace ChatController.HauptKlassen
}
}
public void SendBroadcastMessage()
{
throw new NotImplementedException("SendBroadcastMessage implementieren!");
}

View File

@@ -337,14 +337,14 @@ namespace ChatController.HauptKlassen
}
else
{
if (userDaten.Error?.ChatCodeFailed != null)
if(!(userDaten.Error?.ChatCodeFailed is null))
{
if (_ShouldShowMessageBox)
{
MessageBox.Show("Fehler: " + userDaten.Error.ChatCodeFailed[0] + "\nBitte überprüfen Sie die Anmeldeinformationen.", "Info", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
else if (userDaten.Error?.LoginFailed != null)
else if(!(userDaten.Error?.LoginFailed is null))
{
if (_ShouldShowMessageBox)
{
@@ -387,8 +387,6 @@ namespace ChatController.HauptKlassen
if (!string.IsNullOrEmpty(serverResponse))
{
Debug.WriteLine($"'ChatGruppenDaten' (Gruppen): {serverResponse}");
var jsonDaten = JsonConvert.DeserializeObject<ChatGruppenDaten>(serverResponse);
_AllGroups = jsonDaten;
@@ -422,7 +420,7 @@ namespace ChatController.HauptKlassen
{
var connectionData = JsonConvert.DeserializeObject<UserDaten>(response.Content);
if(connectionData != null && connectionData.Success)
if(connectionData?.Success ?? false)
{
_AuthToken = connectionData.Response.User.Token;
_UserId = connectionData.Response.User.Oid;
@@ -440,11 +438,11 @@ namespace ChatController.HauptKlassen
{
var errorMessage = string.Empty;
if (connectionData?.Error?.ChatCodeFailed != null)
if(!(connectionData?.Error?.ChatCodeFailed is null))
{
errorMessage = $"Fehler: {connectionData.Error.ChatCodeFailed[0]}";
}
else if (connectionData?.Error?.LoginFailed != null)
else if(!(connectionData?.Error?.LoginFailed is null))
{
errorMessage = $"Fehler: {connectionData.Error.LoginFailed[0]}";
}

View File

@@ -6,7 +6,7 @@ using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Threading;
using ChatController.Annotations;
using ChatController.HauptKlassen;
@@ -15,6 +15,7 @@ using ChatController.Utilities;
using ChatController.Utilities.Extensions;
using Cursors = System.Windows.Input.Cursors;
using MessageBox = System.Windows.MessageBox;
using Panel = System.Windows.Controls.Panel;
using Path = System.IO.Path;
namespace ChatController
@@ -104,7 +105,7 @@ namespace ChatController
private void StartWaitingImmediately()
{
if (_WaitLayer == null)
if (_WaitLayer is null)
{
_WaitLayer = new ChatControlWaitLayer();
Panel.SetZIndex(_WaitLayer, int.MaxValue);
@@ -117,7 +118,7 @@ namespace ChatController
{
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action) delegate
{
if (_WaitLayer != null)
if(!(_WaitLayer is null))
{
RootGrid.Children.Remove(_WaitLayer);
_WaitLayer = null;
@@ -183,7 +184,7 @@ namespace ChatController
{
string line;
while((line = streamReader.ReadLine()) != null)
while(!((line = streamReader.ReadLine()) is null))
{
var encodedTextBytes = Convert.FromBase64String(line);
@@ -199,6 +200,56 @@ namespace ChatController
_ChatCode = lines[1];
}
}
#if DEBUG
var debugFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "debug-info.txt");
if (File.Exists(debugFile))
{
using(var streamReader2 = new StreamReader(debugFile, true))
{
string line;
var counter = 0;
while(!((line = streamReader2.ReadLine()) is null))
{
if(counter == 0)
{
try
{
var encodedTextBytes = Convert.FromBase64String(line);
var plainText = Encoding.UTF8.GetString(encodedTextBytes);
UserName = plainText;
}
catch (Exception)
{
MessageBox.Show("Der Zeile muss im Base64-Format kodiert sein.", "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
else if(counter == 1)
{
try
{
var encodedTextBytes = Convert.FromBase64String(line);
var plainText = Encoding.UTF8.GetString(encodedTextBytes);
Password = plainText;
}
catch (Exception)
{
MessageBox.Show("Der Zeile muss im Base64-Format kodiert sein.", "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
counter++;
}
}
}
#endif
}
catch(Exception e)
{

View File

@@ -0,0 +1,50 @@
<Window x:Class="ChatController.OwnChatMessageBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:converter="clr-namespace:ChatController.Converter"
mc:Ignorable="d" ResizeMode="NoResize" Title="{Binding Path=Title, UpdateSourceTrigger=PropertyChanged}"
d:DesignHeight="450" d:DesignWidth="400" WindowStartupLocation="CenterOwner"
Height="150" Width="400" >
<Window.Resources>
<converter:OwnChatNullVisibilityConverter x:Key="NullVisibilityConverter" />
<Style x:Key="OrangeButtonStyle" TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="#FF5A00" />
<Setter Property="Background" Value="#FF5A00" />
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" Background="#FF5A00" CornerRadius="5" Padding="5,2">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF988F" TargetName="Border" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#FF7654" TargetName="Border" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="LightGray" TargetName="Border" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid Margin="5" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Path=MessageBoxText, UpdateSourceTrigger=PropertyChanged}" FontSize="14" Margin="5" TextWrapping="Wrap"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Stretch">
<Button Margin="5" FontSize="14" Content="{Binding Path=PositiveButtonText, UpdateSourceTrigger=PropertyChanged}" Width="150" Style="{StaticResource OrangeButtonStyle}" Height="30" Click="PositiveButton_OnClick" Visibility="{Binding Path=PositiveButtonText, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource NullVisibilityConverter}}" />
<Button Margin="5" FontSize="14" Content="{Binding Path=CloseButtonText, UpdateSourceTrigger=PropertyChanged}" Width="150" Style="{StaticResource OrangeButtonStyle}" Click="CloseButton_OnClick" />
</StackPanel>
</Grid>
</Window>

View File

@@ -0,0 +1,76 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using ChatController.Annotations;
namespace ChatController
{
public partial class OwnChatMessageBox : INotifyPropertyChanged
{
private string _MessageBoxText;
public string MessageBoxText
{
get => _MessageBoxText;
set
{
_MessageBoxText = value;
OnPropertyChanged(nameof(MessageBoxText));
}
}
private string _PositiveButtonText;
public string PositiveButtonText
{
get => _PositiveButtonText;
set
{
_PositiveButtonText = value;
OnPropertyChanged(nameof(PositiveButtonText));
}
}
private string _CloseButtonText;
public string CloseButtonText
{
get => _CloseButtonText;
set
{
_CloseButtonText = value;
OnPropertyChanged(nameof(CloseButtonText));
}
}
public OwnChatMessageBox(string positiveButtonText, string closeButtonText, string messageBoxText, string title)
{
InitializeComponent();
DataContext = this;
PositiveButtonText = positiveButtonText;
CloseButtonText = string.IsNullOrWhiteSpace(closeButtonText) ? "Schließen" : closeButtonText;
MessageBoxText = messageBoxText;
Title = title;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void PositiveButton_OnClick(object sender, RoutedEventArgs e)
{
DialogResult = true;
Close();
}
private void CloseButton_OnClick(object sender, RoutedEventArgs e)
{
DialogResult = false;
Close();
}
}
}

View File

@@ -137,7 +137,7 @@ namespace ChatController.Annotations
/// </summary>
/// <example><code>
/// void Foo(string param) {
/// if (param == null)
/// if (param is null)
/// throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
/// }
/// </code></example>

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 991 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

View File

@@ -5,11 +5,14 @@ using System.Runtime.CompilerServices;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using ChatController.Annotations;
using ChatController.Core;
namespace ChatController.Utilities
{
public class BroadcastMessage : INotifyPropertyChanged
public class ChatMessageFileWrapper : INotifyPropertyChanged
{
public string FileName => !string.IsNullOrWhiteSpace(OriginalFilePath) ? Path.GetFileName(OriginalFilePath) : null;
private string _OriginalFilePath;
public string OriginalFilePath
{
@@ -18,6 +21,7 @@ namespace ChatController.Utilities
{
_OriginalFilePath = value;
OnPropertyChanged(nameof(OriginalFilePath));
OnPropertyChanged(nameof(FileName));
}
}
@@ -32,29 +36,39 @@ namespace ChatController.Utilities
}
}
private ImageSource _BroadcastMessageImageSource;
private ImageSource _ChatMessageImageSource;
public ImageSource BroadcastMessageImageSource
public ImageSource ChatMessageImageSource
{
get => _BroadcastMessageImageSource;
set
get => _ChatMessageImageSource;
private set
{
_BroadcastMessageImageSource = value;
OnPropertyChanged(nameof(BroadcastMessageImageSource));
_ChatMessageImageSource = value;
OnPropertyChanged(nameof(ChatMessageImageSource));
}
}
public BroadcastMessage(string originalFilePath, string scaledFilePath)
public ChatMessageFileWrapper(string originalFilePath, string scaledFilePath, string thumbnailUrl)
{
OriginalFilePath = originalFilePath;
ScaledFilePath = scaledFilePath;
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri(scaledFilePath);
bitmap.EndInit();
var uri = new Uri(scaledFilePath);
BroadcastMessageImageSource = bitmap;
if (Constants.ImageFileExtensions.Contains(Path.GetExtension(scaledFilePath).ToUpperInvariant()) && uri.IsFile)
{
var bitmap = new BitmapImage(uri);
bitmap.Freeze();
ChatMessageImageSource = bitmap;
}
else
{
Utils.DownloadDocumentThumbnail(thumbnailUrl, imageSource =>
{
ChatMessageImageSource = imageSource;
});
}
}
public event PropertyChangedEventHandler PropertyChanged;

View File

@@ -49,7 +49,7 @@ namespace ChatController.Utilities.Extensions
public void Sort()
{
if (_Comparer != null)
if (!(_Comparer is null))
{
DisconnectHandler();
var lTemp = this.ToList();

View File

@@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
@@ -13,6 +14,13 @@ namespace ChatController.Utilities
{
try
{
var isImageFile = Constants.ImageFileExtensions.Contains(Path.GetExtension(pFile).ToUpperInvariant());
if(!isImageFile)
{
return pFile;
}
byte[] mediaFile;
using(Stream reader = File.OpenRead(pFile))
{
@@ -79,7 +87,8 @@ namespace ChatController.Utilities
graphics.DrawImage(scaledBitmap, (int)width, (int)height);
}
var filePath = Path.GetTempPath() + Guid.NewGuid() + pFormat;
// tmp_img_owch_
var filePath = $"{Path.GetTempPath()}{Guid.NewGuid()}_tmp_img_owch{pFormat}";
if(pFormat.Equals(".JPG") || pFormat.Equals(".JPE") || pFormat.Equals(".JPEG") || pFormat.Equals(".BMP"))
{
@@ -127,5 +136,30 @@ namespace ChatController.Utilities
return fileInfo.Length > maxFileSize;
}
public static bool IsFileLocked(string path)
{
if(!File.Exists(path))
{
return false;
}
try
{
var file = new FileInfo(path);
using (var stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None))
{
stream.Close();
}
}
catch(IOException ioException)
{
Debug.WriteLine($"Error (FileUtils.IsFileLocked): {ioException.Message}");
return true;
}
return false;
}
}
}

View File

@@ -14,14 +14,11 @@ using System.Windows;
using System.Windows.Documents;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using ChatController.Core;
using RestSharp;
using MessageBox = System.Windows.MessageBox;
using PixelFormat = System.Drawing.Imaging.PixelFormat;
using Point = System.Drawing.Point;
using Size = System.Drawing.Size;
namespace ChatController.Utilities
{
@@ -138,7 +135,7 @@ namespace ChatController.Utilities
var cachedImage = cache.GetImageSourceFromCache(key, uri, cacheCategory);
if (cachedImage != null)
if(!(cachedImage is null))
{
callback?.Invoke(cachedImage);
return;
@@ -151,6 +148,29 @@ namespace ChatController.Utilities
});
}
public static void DownloadDocumentThumbnail(string uri, Action<ImageSource> callback)
{
if (string.IsNullOrEmpty(uri))
{
callback?.Invoke(null);
return;
}
var cache = OwnChatCache.GetInstance();
if(!(cache.DocumentThumbnail is null))
{
callback?.Invoke(cache.DocumentThumbnail);
return;
}
DownloadImage(uri, imageSource =>
{
cache.DocumentThumbnail = imageSource;
callback?.Invoke(imageSource);
});
}
private static ImageSource GetDefaultImageSource(bool pIsGroup, bool pIsEmployee)
{
var defaultImage = Constants.EmployeeDefaultImagePath;
@@ -175,6 +195,10 @@ namespace ChatController.Utilities
}
public static ImageSource GetPicturePlaceholder()
{
var cache = OwnChatCache.GetInstance();
if(cache.ImagePlaceholder is null)
{
var resultBitmapImage = new BitmapImage();
@@ -183,14 +207,17 @@ namespace ChatController.Utilities
resultBitmapImage.EndInit();
resultBitmapImage.Freeze();
return resultBitmapImage;
cache.ImagePlaceholder = resultBitmapImage;
}
return cache.ImagePlaceholder;
}
public static string ReadStream(WebResponse response)
{
var dataStream = response.GetResponseStream();
if (dataStream == null)
if(dataStream is null)
{
return null;
}
@@ -257,9 +284,9 @@ namespace ChatController.Utilities
return memoryStream.ToArray();
}
}
catch (Exception e)
catch(Exception exception)
{
MessageBox.Show("Fehler: " + e.Message, "Fehler", MessageBoxButton.OK);
MessageBox.Show("Fehler: " + exception.Message, "Fehler", MessageBoxButton.OK);
return null;
}
}
@@ -453,7 +480,7 @@ namespace ChatController.Utilities
https://test.ownchat.de/message/view-image/{customerid}/{group}/{height}/{filename}
*/
if (uri != null && uri.Contains("/"))
if(uri?.Contains("/") ?? false)
{
var splitUri = uri.Split('/');
@@ -477,7 +504,7 @@ namespace ChatController.Utilities
{
var result = new ObservableCollection<Inline>();
if(messageText == null)
if(messageText is null)
{
return result;
}

View File

@@ -1,17 +1,6 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace ownChat
namespace ownChat
{
/// <summary>
/// Interaktionslogik für "App.xaml"
/// </summary>
public partial class App : Application
public partial class App
{
}
}

View File

@@ -5,8 +5,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:cc="clr-namespace:ChatController;assembly=ChatController"
mc:Ignorable="d" WindowStartupLocation="CenterScreen" Icon="pack://application:,,,/ChatController;component/Ressourcen/ownchat_icon.png"
SizeChanged="MainWindow_OnSizeChanged" MinHeight="610"
Title="ownChat Desktop" Height="700" Width="900" x:Name="MainView" Closed="MainWindow_OnClosed">
MinHeight="610"
Title="ownChat Desktop" Height="700" Width="900" Closed="MainWindow_OnClosed">
<Grid>
<cc:ChatMainControl x:Name="ChatMainControl" OnEmojii="ChatMainControl_OnOnEmojii"></cc:ChatMainControl>
</Grid>

View File

@@ -1,5 +1,4 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows;
@@ -21,7 +20,6 @@ namespace ownChat
ChatMainControl.ContainingWindow = this;
ChatMainControl.InitMitChatdaten(x);
ChatMainControl.ResetStyle();
_EmojiView = new ChatEmojisView(ChatMainControl);
}
@@ -50,10 +48,5 @@ namespace ownChat
Environment.Exit(0);
}
private void MainWindow_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
Debug.WriteLine($"+++>ActualHeight: {ActualHeight}");
}
}
}

View File

@@ -137,7 +137,7 @@ namespace ownChat.Annotations
/// </summary>
/// <example><code>
/// void Foo(string param) {
/// if (param == null)
/// if (param is null)
/// throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
/// }
/// </code></example>