Massennachricht hinzugefügt

Optik an die vom Android- und Webclient angepasst
Asynchrone Methoden verbessert
This commit is contained in:
LynJet
2022-07-11 16:01:14 +02:00
parent 6daa1ce73a
commit 410945af20
17 changed files with 929 additions and 171 deletions

View File

@@ -67,6 +67,7 @@
<DependentUpon>ChatMainControl.xaml</DependentUpon> <DependentUpon>ChatMainControl.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Converter\BoolToVisibilityConverter.cs" /> <Compile Include="Converter\BoolToVisibilityConverter.cs" />
<Compile Include="Converter\BroadcastCheckBoxVisibilityMultiConverter.cs" />
<Compile Include="Converter\StringEmptyToVisibilityConverter.cs" /> <Compile Include="Converter\StringEmptyToVisibilityConverter.cs" />
<Compile Include="Converter\StringToBoolConverter.cs" /> <Compile Include="Converter\StringToBoolConverter.cs" />
<Compile Include="Converter\UserProfilePictureVisibilityConverter.cs" /> <Compile Include="Converter\UserProfilePictureVisibilityConverter.cs" />
@@ -99,10 +100,14 @@
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<DependentUpon>Resource.resx</DependentUpon> <DependentUpon>Resource.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="Utilities\BroadcastMessage.cs" />
<Compile Include="Utilities\BroadcastProgressReportModel.cs" />
<Compile Include="Utilities\Constants.cs" /> <Compile Include="Utilities\Constants.cs" />
<Compile Include="Utilities\Extensions\ControlExtensions.cs" /> <Compile Include="Utilities\Extensions\ControlExtensions.cs" />
<Compile Include="Utilities\Extensions\DateTimeExtensions.cs" /> <Compile Include="Utilities\Extensions\DateTimeExtensions.cs" />
<Compile Include="Utilities\Extensions\ObservableSortCollection.cs" />
<Compile Include="Utilities\FileUtils.cs" /> <Compile Include="Utilities\FileUtils.cs" />
<Compile Include="Utilities\ListItemHelper.cs" />
<Compile Include="Utilities\OwnChatEnums.cs" /> <Compile Include="Utilities\OwnChatEnums.cs" />
<Compile Include="Utilities\SyncFileInfoStruct.cs" /> <Compile Include="Utilities\SyncFileInfoStruct.cs" />
<Compile Include="Utilities\Utils.cs" /> <Compile Include="Utilities\Utils.cs" />
@@ -148,6 +153,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="ownchat_favicon.ico" /> <Content Include="ownchat_favicon.ico" />
<Resource Include="Ressourcen\TasksSolid.png" />
<Resource Include="Ressourcen\ownchat_image_placeholder.png" /> <Resource Include="Ressourcen\ownchat_image_placeholder.png" />
<Resource Include="Ressourcen\warning-exclamation-mark.png" /> <Resource Include="Ressourcen\warning-exclamation-mark.png" />
<None Include="packages.config" /> <None Include="packages.config" />

View File

@@ -4,10 +4,11 @@ using System.ComponentModel;
using System.Windows.Documents; using System.Windows.Documents;
using System.Windows.Media; using System.Windows.Media;
using ChatController.Core; using ChatController.Core;
using ChatController.HauptKlassen;
using ChatController.Utilities; using ChatController.Utilities;
using static System.Windows.HorizontalAlignment; using static System.Windows.HorizontalAlignment;
using Application = System.Windows.Application; using Application = System.Windows.Application;
using Brush = System.Windows.Media.Brush;
using Color = System.Windows.Media.Color;
using HorizontalAlignment = System.Windows.HorizontalAlignment; using HorizontalAlignment = System.Windows.HorizontalAlignment;
namespace ChatController.ChatKlassen namespace ChatController.ChatKlassen
@@ -147,9 +148,11 @@ namespace ChatController.ChatKlassen
public string SendTimeString => SendTime.Date == DateTime.Today ? $"Heute {SendTime:HH:mm}" : SendTime.ToString("dd. MMM HH:mm"); public string SendTimeString => SendTime.Date == DateTime.Today ? $"Heute {SendTime:HH:mm}" : SendTime.ToString("dd. MMM HH:mm");
public Brush BorderBrush => IsSeparator ? new SolidColorBrush(Colors.Transparent) : IsMyMessage ? new SolidColorBrush(Color.FromRgb(255, 90, 0)) : new SolidColorBrush(Color.FromRgb(229, 229, 229)); public Brush BorderBrush => IsSeparator ? new SolidColorBrush(Colors.Transparent) : IsMyMessage ? new SolidColorBrush(Color.FromRgb(255, 90, 0)) : new SolidColorBrush(Color.FromRgb(255, 255, 255));
public Brush HighlightedBorderBrush => IsSeparator ? new SolidColorBrush(Colors.Transparent) : IsMyMessage ? new SolidColorBrush(Color.FromRgb(255, 153, 153)) : new SolidColorBrush(Color.FromRgb(247, 247, 247)); public Brush HighlightedBorderBrush => IsSeparator ? new SolidColorBrush(Colors.Transparent) : IsMyMessage ? new SolidColorBrush(Color.FromRgb(255, 152, 143)) : new SolidColorBrush(Color.FromRgb(247, 247, 247));
public Brush TextColor => !IsMyMessage && !IsSeparator ? new SolidColorBrush(Colors.Black) : new SolidColorBrush(Colors.White);
public Brush Foreground => new BrushConverter().ConvertFromString("#505050") as SolidColorBrush; public Brush Foreground => new BrushConverter().ConvertFromString("#505050") as SolidColorBrush;

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using ChatController.Core; using ChatController.Core;
using ChatController.LoginKlassen; using ChatController.LoginKlassen;
@@ -179,4 +180,14 @@ namespace ChatController.ChatKlassen
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName)); handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }
} }
public class ContactDependencyObject : DependencyObject
{
public Contact Contact { get; set; }
public ContactDependencyObject(Contact contact)
{
Contact = contact;
}
}
} }

View File

@@ -7,18 +7,132 @@
xmlns:chatKlassen="clr-namespace:ChatController.ChatKlassen" xmlns:chatKlassen="clr-namespace:ChatController.ChatKlassen"
xmlns:core="clr-namespace:ChatController.Core" xmlns:core="clr-namespace:ChatController.Core"
xmlns:chatController="clr-namespace:ChatController" xmlns:chatController="clr-namespace:ChatController"
mc:Ignorable="d" x:Name="ChatControlling" xmlns:utilities="clr-namespace:ChatController.Utilities"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600" d:DesignHeight="300" d:DesignWidth="600"
Loaded="ChatMainControl_OnLoaded" Loaded="ChatMainControl_OnLoaded"
SnapsToDevicePixels="True" d:DataContext="{d:DesignData ChatMainControl}"> SnapsToDevicePixels="True" d:DataContext="{d:DesignData ChatMainControl}">
<UserControl.Resources> <UserControl.Resources>
<converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" /> <converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<converter:StringEmptyToVisibilityConverter x:Key="StringEmptyToVisibilityConverter" /> <converter:StringEmptyToVisibilityConverter x:Key="StringEmptyToVisibilityConverter" />
<converter:StringToBoolConverter x:Key="StringToBoolConverter" />
<converter:UserProfilePictureVisibilityConverter x:Key="UserProfilePictureVisibilityConverter" /> <converter:UserProfilePictureVisibilityConverter x:Key="UserProfilePictureVisibilityConverter" />
<converter:BroadcastCheckBoxVisibilityMultiConverter x:Key="BroadcastCheckBoxVisibilityMultiConverter" />
<SolidColorBrush x:Key="DarkBackColor" Color="#FFA9B8C2" /> <!--<SolidColorBrush x:Key="DarkBackColor" Color="#A9B8C2" />-->
<SolidColorBrush x:Key="LightBackColor" Color="#E8EFF4" /> <SolidColorBrush x:Key="DarkBackColor" Color="#A9B8C2" />
<SolidColorBrush x:Key="LightBackColor" Color="#F3F3F3" />
<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>
<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" />
<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>
</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>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MainNavigationScrollViewer" TargetType="{x:Type ScrollViewer}"> <Style x:Key="MainNavigationScrollViewer" TargetType="{x:Type ScrollViewer}">
<Setter Property="OverridesDefaultStyle" Value="True"/> <Setter Property="OverridesDefaultStyle" Value="True"/>
@@ -77,30 +191,47 @@
<Setter.Value> <Setter.Value>
<ControlTemplate> <ControlTemplate>
<Grid> <Grid>
<Border x:Name="ItemBorder" MinHeight="20" Background="White" BorderThickness="0,0,0,1" BorderBrush="{StaticResource LightBackColor}"> <Border x:Name="ItemBorder" MinHeight="20" Background="White" BorderThickness="0,0,0,0" BorderBrush="{StaticResource LightBackColor}">
</Border> </Border>
<Border x:Name="ItemContent" MinHeight="20"> <Border x:Name="ItemContent" MinHeight="20">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5,3,5,3" OpacityMask="{x:Null}" SnapsToDevicePixels="True"> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5,3,5,3" OpacityMask="{x:Null}" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="7"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="35"/> <ColumnDefinition Width="35"/>
<ColumnDefinition Width="7"/> <ColumnDefinition Width="7"/>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="7"/> <ColumnDefinition Width="7"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<CheckBox Grid.Column="0" VerticalAlignment="Center" Margin="0,0,7,0"
Click="ContactCheckBox_OnClick" Checked="ContactCheckBox_OnChecked" Unchecked="ContactCheckBox_OnChecked"
IsChecked="{Binding Path=(utilities:ListItemHelper.IsChecked), Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<CheckBox.Visibility>
<MultiBinding Converter="{StaticResource BroadcastCheckBoxVisibilityMultiConverter}">
<Binding Path="Chat.IsInBroadcastMode" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type chatController:ChatMainControl}}" UpdateSourceTrigger="PropertyChanged" />
<Binding Path="Contact.IsChatMessageInputGridVisible" />
</MultiBinding>
</CheckBox.Visibility>
<CheckBox.Style>
<Style TargetType="{x:Type CheckBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(utilities:ListItemHelper.IsChecked), Mode=TwoWay}" Value="False" />
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
<Ellipse Grid.Column="1" Width='32' Height='32' RenderOptions.BitmapScalingMode="HighQuality"> <Ellipse Grid.Column="1" Width='32' Height='32' RenderOptions.BitmapScalingMode="HighQuality">
<Ellipse.Fill> <Ellipse.Fill>
<ImageBrush ImageSource='{Binding Image, UpdateSourceTrigger=PropertyChanged}' Stretch='UniformToFill' RenderOptions.BitmapScalingMode="HighQuality" /> <ImageBrush ImageSource='{Binding Contact.Image, UpdateSourceTrigger=PropertyChanged}' Stretch='UniformToFill' RenderOptions.BitmapScalingMode="HighQuality" />
</Ellipse.Fill> </Ellipse.Fill>
</Ellipse> </Ellipse>
<Grid Grid.Column="3" > <Grid Grid.Column="3">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Text="{Binding Path=Name, FallbackValue=FirstName}" Foreground="{Binding Path=AccentColorBrush}" FontSize="16" Margin="1" /> <TextBlock Text="{Binding Path=Contact.Name, FallbackValue=FirstName}" Foreground="{Binding Path=Contact.AccentColorBrush}" FontSize="16" Margin="1" />
<TextBlock Text="{Binding Path=ReceivedMessage.Text}" Grid.Row="1" FontSize="14" Foreground="{Binding Path=Color}" Margin="1" /> <TextBlock Text="{Binding Path=Contact.ReceivedMessage.Text}" Grid.Row="1" FontSize="14" Foreground="{Binding Path=Contact.Color}" Margin="1" />
</Grid> </Grid>
</Grid> </Grid>
</Border> </Border>
@@ -171,8 +302,8 @@
<Grid Grid.Column="0" Grid.Row="0" > <Grid Grid.Column="0" Grid.Row="0" >
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="50"/> <RowDefinition Height="50"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
@@ -188,9 +319,16 @@
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<StackPanel x:Name="ReloadGruppen" Grid.Row="0" Grid.Column="1" Height="25" Width="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" VerticalAlignment="Center" VerticalContentAlignment="Center" Width="25" Height="25" Click="ButtonReloadGruppen_OnClick" > <Button Background="Transparent" HorizontalAlignment="Right" BorderThickness="0"
<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" /> 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" />
</Button> </Button>
</StackPanel> </StackPanel>
@@ -201,12 +339,16 @@
<!-- region Kontaktliste --> <!-- region Kontaktliste -->
<Grid Grid.Column="0" Grid.Row="1" > <Grid Grid.Column="0" Grid.Row="1" >
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ListView x:Name="Clientlist" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="0" VerticalAlignment="Stretch" BorderThickness="0" Background="White" <CheckBox Grid.Row="0" Margin="5" x:Name="SelectAllContactsCheckBox" FontSize="16" Content="Alle auswählen" VerticalContentAlignment="Center" 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"
ItemsSource="{Binding ContactList, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding ContactList, UpdateSourceTrigger=PropertyChanged}"
ItemContainerStyle="{StaticResource ContactListBoxItemStyle}" SelectionChanged="Clientlist_OnSelectionChanged" Style="{StaticResource ContactListStyle}"> ItemContainerStyle="{StaticResource ContactListBoxItemStyle}" SelectionChanged="Clientlist_OnSelectionChanged" Style="{StaticResource ContactListStyle}">
</ListView> </ListView>
@@ -254,6 +396,7 @@
Background="{StaticResource LightBackColor}" Background="{StaticResource LightBackColor}"
ContextMenuOpening="Chat_OnContextMenuOpening" ContextMenuOpening="Chat_OnContextMenuOpening"
Padding="20" Padding="20"
Visibility="{Binding Path=Chat.IsInBroadcastMode, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type chatController:ChatMainControl}}, Converter={StaticResource BoolToVisibilityConverter}}"
d:DataContext="{d:DesignData ChatMessage}"> d:DataContext="{d:DesignData ChatMessage}">
<ListBox.ItemContainerStyle> <ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem"> <Style TargetType="ListBoxItem">
@@ -334,11 +477,15 @@
<DockPanel Grid.Column="1" Grid.ColumnSpan="3" MinHeight="15" Margin="5" LastChildFill="True" Visibility="{Binding IsSeparator, Converter={StaticResource BoolToVisibilityConverter}}"> <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"> <StackPanel DockPanel.Dock="Bottom" Orientation="Vertical">
<Image ToolTip="Dokument öffnen" Height="{Binding ThumbnailPlaceholderHeight, UpdateSourceTrigger=PropertyChanged}" Width="150" Source="{Binding Path=Thumbnail, UpdateSourceTrigger=PropertyChanged}" Stretch="Uniform" VerticalAlignment="Center" HorizontalAlignment="Center" /> <Image ToolTip="Dokument öffnen" Height="{Binding ThumbnailPlaceholderHeight, UpdateSourceTrigger=PropertyChanged}" Width="150"
<Image MaxWidth="300" Height="{Binding PicturePlaceholderHeight, UpdateSourceTrigger=PropertyChanged}" Source="{Binding Path=PictureSource, UpdateSourceTrigger=PropertyChanged}" x:Name="imgChatMessage" Stretch="UniformToFill" /> Source="{Binding Path=Thumbnail, UpdateSourceTrigger=PropertyChanged}"
Stretch="Uniform" VerticalAlignment="Center" HorizontalAlignment="Center" />
<Image MaxHeight="300"
Source="{Binding Path=PictureSource, UpdateSourceTrigger=PropertyChanged}"
x:Name="imgChatMessage" Stretch="Uniform" RenderOptions.BitmapScalingMode="HighQuality" />
<core:OwnChatRichTextBox VerticalAlignment="Center" InlineList="{Binding MessageInlines, UpdateSourceTrigger=PropertyChanged}" <core:OwnChatRichTextBox VerticalAlignment="Center" InlineList="{Binding MessageInlines, UpdateSourceTrigger=PropertyChanged}"
MinWidth="0" MaxWidth="{Binding MessageMaxWidth}" FontSize="14" IsReadOnly="True" MinWidth="0" MaxWidth="{Binding MessageMaxWidth}" FontSize="14" IsReadOnly="True"
HorizontalAlignment="{Binding HorizontalAlignmentValue}" HorizontalAlignment="{Binding HorizontalAlignmentValue}" Foreground="{Binding TextColor, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
BorderThickness="0" Background="Transparent" IsDocumentEnabled="True" Margin="-5,0,0,0" /> BorderThickness="0" Background="Transparent" IsDocumentEnabled="True" Margin="-5,0,0,0" />
</StackPanel> </StackPanel>
<StackPanel DockPanel.Dock="Left" Margin="0,0,0,0"> <StackPanel DockPanel.Dock="Left" Margin="0,0,0,0">
@@ -368,6 +515,24 @@
</ListBox.ItemTemplate> </ListBox.ItemTemplate>
</ListBox> </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">
<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" />
</StackPanel>
</Grid>
<Grid Grid.Row="2" Visibility="{Binding ChatMessageInputGridVisibility}" VerticalAlignment="Stretch" MinHeight="25" MaxHeight="200"> <Grid Grid.Row="2" Visibility="{Binding ChatMessageInputGridVisibility}" VerticalAlignment="Stretch" MinHeight="25" MaxHeight="200">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
@@ -392,6 +557,7 @@
GotFocus="Chatbox_OnGotFocus" GotFocus="Chatbox_OnGotFocus"
AcceptsReturn="True" AcceptsReturn="True"
KeyDown="Chatbox_OnKeyDownHandler" KeyDown="Chatbox_OnKeyDownHandler"
KeyUp="Chatbox_OnKeyUpHandler"
TextChanged="Chatbox_OnTextChanged"> TextChanged="Chatbox_OnTextChanged">
<TextBox.Resources> <TextBox.Resources>
<Style TargetType="{x:Type Border}"> <Style TargetType="{x:Type Border}">
@@ -417,62 +583,29 @@
</Style> </Style>
</TextBlock.Resources> </TextBlock.Resources>
</TextBlock> </TextBlock>
<Button Grid.Column="1" <Button Grid.Column="1" Margin="2" x:Name="MediaButton" Background="Transparent"
Margin="2" Width="28" Height="28" BorderThickness="0" Padding="2"
x:Name="MediaButton" Visibility="{Binding Chat.IsInBroadcastMode, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolToVisibilityConverter}}"
Background="Transparent" VerticalAlignment="Bottom" ToolTip="Datei einfügen" Click="MediaButton_OnClick" >
Width="28"
Height="28"
BorderThickness="0"
Padding="2"
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"/> <Image Width="22" Height="22" Source='pack://application:,,,/ChatController;component/Ressourcen/paperclip2.png' RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center"/>
</Button> </Button>
<Button Grid.Column="2" <Button Grid.Column="1" Margin="2" Background="Transparent"
Width="28" Width="28" Height="28" BorderThickness="0" Padding="2"
Height="28" Visibility="{Binding Path=Chat.IsInBroadcastMode, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}"
BorderThickness="0" VerticalAlignment="Bottom" ToolTip="Datei einfügen" Click="AddMediaFileToBroadcastMessage_OnClick">
Background="Transparent" <Image Width="22" Height="22" Source="pack://application:,,,/ChatController;component/Ressourcen/paperclip2.png" RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
x:Name="EmojiButton" </Button>
Margin="2" <Button Grid.Column="2" Width="28" Height="28" BorderThickness="0"
Padding="0" Background="Transparent" x:Name="EmojiButton" Margin="2" Padding="0"
VerticalAlignment="Bottom" VerticalAlignment="Bottom" ToolTip="Emoji einfügen" Click="EmojiButton_OnClick">
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" /> <Image Width="24" Height="24" Source='pack://application:,,,/ChatController;component/Ressourcen/glucklicher.png' RenderOptions.BitmapScalingMode="HighQuality" HorizontalAlignment="Center" />
</Button> </Button>
<Button x:Name="SendButton" Height="25" Content="Senden" Margin="3" Grid.Column="3" VerticalAlignment="Bottom" <Button x:Name="SendButton" Height="25" Content="Senden" Margin="3" Grid.Column="3" VerticalAlignment="Bottom" Style="{StaticResource OrangeButtonStyle}"
Click="SendButton_OnClick" IsEnabled="{Binding ElementName=Chatbox, Path=Text, Converter={StaticResource StringToBoolConverter}}"> Visibility="{Binding Chat.IsInBroadcastMode, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolToVisibilityConverter}}"
<Button.Style> Click="SendButton_OnClick" IsEnabled="{Binding IsSendButtonEnabled, UpdateSourceTrigger=PropertyChanged}" />
<Style TargetType="{x:Type Button}"> <Button Height="25" Content="Senden" Margin="3" Grid.Column="3" VerticalAlignment="Bottom" Style="{StaticResource OrangeButtonStyle}"
<Setter Property="BorderBrush" Value="#ff5e00" /> Visibility="{Binding Path=Chat.IsInBroadcastMode, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=reverse}"
<Setter Property="Background" Value="#ff5e00" /> Click="SendBroatcastButton_OnClick" IsEnabled="{Binding IsBroadcastButtonEnabled, UpdateSourceTrigger=PropertyChanged}" />
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" Background="#ff5300" CornerRadius="5" Padding="5,2">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#ff9999" TargetName="Border" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#ff3a00" TargetName="Border" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="LightGray" TargetName="Border" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>

View File

@@ -8,6 +8,7 @@ using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Data; using System.Windows.Data;
@@ -25,6 +26,7 @@ using ChatController.Utilities;
using ChatController.Utilities.Extensions; using ChatController.Utilities.Extensions;
using Application = System.Windows.Forms.Application; using Application = System.Windows.Forms.Application;
using Button = System.Windows.Controls.Button; using Button = System.Windows.Controls.Button;
using CheckBox = System.Windows.Controls.CheckBox;
using Cursors = System.Windows.Input.Cursors; using Cursors = System.Windows.Input.Cursors;
using DataFormats = System.Windows.DataFormats; using DataFormats = System.Windows.DataFormats;
using KeyEventArgs = System.Windows.Input.KeyEventArgs; using KeyEventArgs = System.Windows.Input.KeyEventArgs;
@@ -112,11 +114,17 @@ namespace ChatController
} }
} }
public ObservableCollection<Contact> ContactList // ToDo: Hier die ContactDepenencyObject-Klasse benutzen wie im Kalender des BeWoPlaners!
public ObservableSortCollection<ContactDependencyObject> ContactList
{ {
get get => _ContactList ?? (_ContactList = new ObservableSortCollection<ContactDependencyObject>());
set
{ {
return _ContactList == null ? new ObservableCollection<Contact>() : new ObservableCollection<Contact>(_ContactList.OrderByDescending(contact => contact.TimeStamp)); _ContactList = new ObservableSortCollection<ContactDependencyObject>(value);
_ContactList.Sort((x, y) => DateTime.Compare(y.Contact.TimeStamp, x.Contact.TimeStamp));
OnPropertyChanged(nameof(ContactList));
} }
} }
@@ -124,16 +132,21 @@ namespace ChatController
{ {
get get
{ {
if(_CurrentContact is null) if(_CurrentContact is null && Chat?.IsInBroadcastMode == false)
{ {
return Visibility.Collapsed; return Visibility.Collapsed;
} }
return _CurrentContact.IsChatMessageInputGridVisible ? Visibility.Visible : 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;
} }
} }
private List<Contact> _ContactList; private ObservableSortCollection<ContactDependencyObject> _ContactList;
private bool _ScrollPrueferAktivieren; private bool _ScrollPrueferAktivieren;
@@ -150,19 +163,18 @@ namespace ChatController
public ChatMainControl() public ChatMainControl()
{ {
InitializeComponent(); InitializeComponent();
_ThreadExceptionImageSource = new BitmapImage(new Uri("pack://application:,,,/ChatController;component/Ressourcen/warning-exclamation-mark.png", UriKind.Absolute)); _ThreadExceptionImageSource = new BitmapImage(new Uri("pack://application:,,,/ChatController;component/Ressourcen/warning-exclamation-mark.png", UriKind.Absolute));
_ChatMessages = new ObservableCollection<ChatMessage>(); _ChatMessages = new ObservableCollection<ChatMessage>();
ChatMessages = CollectionViewSource.GetDefaultView(_ChatMessages) as ListCollectionView; ChatMessages = CollectionViewSource.GetDefaultView(_ChatMessages) as ListCollectionView;
if (!(ChatMessages is null)) if (!(ChatMessages is null))
{ {
ChatMessages.CustomSort = new ChatMessageComparer(); ChatMessages.CustomSort = new ChatMessageComparer();
} }
DataContext = this; DataContext = this;
ReloadGruppen.Visibility = Visibility.Collapsed;
} }
private void ContainingWindowOnDeactivated(object sender, EventArgs e) private void ContainingWindowOnDeactivated(object sender, EventArgs e)
@@ -202,20 +214,27 @@ namespace ChatController
OnPropertyChanged(nameof(Chat)); OnPropertyChanged(nameof(Chat));
_ContactList = Chat.AddContacts(); _ContactList = new ObservableSortCollection<ContactDependencyObject>();
foreach(var contact in Chat.AddContacts())
{
ContactList.Add(new ContactDependencyObject(contact));
}
ContactList.Sort((x, y) => DateTime.Compare(y.Contact.TimeStamp, x.Contact.TimeStamp));
OnPropertyChanged(nameof(ContactList)); OnPropertyChanged(nameof(ContactList));
ReadNewSyncFile(); ReadNewSyncFile();
foreach (var contact in _ContactList) foreach (var contactDependencyObject in _ContactList)
{ {
if (_GroupId2DateTime.ContainsKey(contact.GroupId)) if (_GroupId2DateTime.ContainsKey(contactDependencyObject.Contact.GroupId))
{ {
var isUnread = _GroupId2DateTime[contact.GroupId].IsUnread; var isUnread = _GroupId2DateTime[contactDependencyObject.Contact.GroupId].IsUnread;
contact.IsNewMessage = isUnread; contactDependencyObject.Contact.IsNewMessage = isUnread;
contact.HasUnreadMessages = contact.IsNewMessage; contactDependencyObject.Contact.HasUnreadMessages = contactDependencyObject.Contact.IsNewMessage;
} }
} }
@@ -230,11 +249,11 @@ namespace ChatController
{ {
var notificationIcon = Resource.ownchat_favicon; var notificationIcon = Resource.ownchat_favicon;
var contact = _ContactList.FirstOrDefault(a => a.GroupId == pGroupId); var contact = _ContactList.FirstOrDefault(a => a.Contact.GroupId == pGroupId);
if (contact != null) if (contact != null)
{ {
notificationIcon = Utils.ImageSourceToIcon(contact.Image); notificationIcon = Utils.ImageSourceToIcon(contact.Contact.Image);
} }
var notifyIcon = new NotifyIcon { Icon = notificationIcon, Visible = true, Tag = pMessage }; var notifyIcon = new NotifyIcon { Icon = notificationIcon, Visible = true, Tag = pMessage };
@@ -255,10 +274,10 @@ namespace ChatController
_ContainingWindow.Activate(); _ContainingWindow.Activate();
var selectedContact = _ContactList?.FirstOrDefault(f => f?.GroupId == pGroupId); var selectedContact = _ContactList?.FirstOrDefault(f => f?.Contact.GroupId == pGroupId);
if(selectedContact != null) if(selectedContact != null)
{ {
SelectContact(selectedContact); SelectContact(selectedContact.Contact);
} }
}; };
@@ -314,9 +333,14 @@ namespace ChatController
private void Clientlist_OnSelectionChanged(object sender, SelectionChangedEventArgs e) private void Clientlist_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{ {
if(Clientlist?.SelectedItem is Contact selectedContact) if(Chat.IsInBroadcastMode)
{ {
SelectContact(selectedContact); return;
}
if(Clientlist?.SelectedItem is ContactDependencyObject selectedContactDependencyObject)
{
SelectContact(selectedContactDependencyObject.Contact);
} }
} }
@@ -324,7 +348,7 @@ namespace ChatController
{ {
try try
{ {
if (pContact == null) if (pContact is null)
{ {
return; return;
} }
@@ -346,7 +370,7 @@ namespace ChatController
var currentContact = pContact; var currentContact = pContact;
pContact.IsNewMessage = false; pContact.IsNewMessage = false;
var shouldChangeIcon = _ContactList.Any(contact => contact.IsNewMessage); var shouldChangeIcon = _ContactList.Any(contact => contact.Contact.IsNewMessage);
if (shouldChangeIcon) if (shouldChangeIcon)
{ {
ContainingWindow.Icon = Utils.ConvertIconToImageSource(Resource.ownchat_favicon); ContainingWindow.Icon = Utils.ConvertIconToImageSource(Resource.ownchat_favicon);
@@ -354,9 +378,12 @@ namespace ChatController
CurrentContact = currentContact; CurrentContact = currentContact;
if (Clientlist.Items.Contains(pContact)) foreach(ContactDependencyObject item in Clientlist.Items)
{ {
Clientlist.SelectedItem = pContact; if(item.Contact.Equals(pContact))
{
Clientlist.SelectedItem = item;
}
} }
_ChatMessages.Clear(); _ChatMessages.Clear();
@@ -460,9 +487,9 @@ namespace ChatController
} }
} }
private void PasteOnClick(object sender, RoutedEventArgs routedEventArgs) private async void PasteOnClick(object sender, RoutedEventArgs routedEventArgs)
{ {
Chat.Paste(CurrentContact.GroupId,this); await Chat.Paste(CurrentContact.GroupId,this);
} }
private void CopyOnClick(object sender, RoutedEventArgs routedEventArgs) private void CopyOnClick(object sender, RoutedEventArgs routedEventArgs)
@@ -582,7 +609,7 @@ namespace ChatController
} }
} }
private void MediaButton_OnClick(object sender, RoutedEventArgs e) private async void MediaButton_OnClick(object sender, RoutedEventArgs e)
{ {
if(CurrentContact != null) if(CurrentContact != null)
{ {
@@ -600,7 +627,7 @@ namespace ChatController
return; return;
} }
if (!string.IsNullOrWhiteSpace(pathToScaledImage)) if (File.Exists(pathToScaledImage))
{ {
_ChatMessages.AddRangeIfElementsNotIn(Chat.AddNewFile(pathToScaledImage, pathToOriginalImage, CurrentContact.GroupId, GetFirstMessage())); _ChatMessages.AddRangeIfElementsNotIn(Chat.AddNewFile(pathToScaledImage, pathToOriginalImage, CurrentContact.GroupId, GetFirstMessage()));
@@ -610,7 +637,7 @@ namespace ChatController
ChatListBox.ScrollIntoView(currentChatMessage); ChatListBox.ScrollIntoView(currentChatMessage);
Chat.SendFileToContact(CurrentContact, pathToScaledImage,pathToOriginalImage); await Chat.SendFileToContact(CurrentContact, pathToScaledImage, pathToOriginalImage, Chatbox.Text);
if (!string.IsNullOrWhiteSpace(pathToScaledImage) && !pathToScaledImage.Equals(pathToOriginalImage) && File.Exists(pathToScaledImage)) if (!string.IsNullOrWhiteSpace(pathToScaledImage) && !pathToScaledImage.Equals(pathToOriginalImage) && File.Exists(pathToScaledImage))
{ {
@@ -625,8 +652,14 @@ namespace ChatController
} }
} }
private void SendButton_OnClick(object sender, RoutedEventArgs e) private async void SendButton_OnClick(object sender, RoutedEventArgs e)
{ {
if(Chat.IsInBroadcastMode)
{
SendBroadcastMessage();
return;
}
if(CurrentContact != null && !string.IsNullOrEmpty(Chatbox.Text)) if(CurrentContact != null && !string.IsNullOrEmpty(Chatbox.Text))
{ {
var messages2Add = Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId, GetFirstMessage()); var messages2Add = Chat.AddNewMessage(Chatbox.Text, CurrentContact.GroupId, GetFirstMessage());
@@ -639,12 +672,10 @@ namespace ChatController
WpfUtils.ScrollToBottomOfListBox(ChatListBox); WpfUtils.ScrollToBottomOfListBox(ChatListBox);
Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId); await Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId);
Chatbox.Text = string.Empty; Chatbox.Text = string.Empty;
Thread.Sleep(500);
DoSynchro(); DoSynchro();
} }
} }
@@ -672,12 +703,15 @@ namespace ChatController
// ChatListBox.Items.MoveCurrentToLast(); // ChatListBox.Items.MoveCurrentToLast();
// ChatListBox.ScrollIntoView(ChatListBox.Items.CurrentItem); // ChatListBox.ScrollIntoView(ChatListBox.Items.CurrentItem);
// Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId); // Chat.SendMessage(Chatbox.Text, CurrentContact.GroupId);
// Chatbox.Text = string.Empty; // Chatbox.Text = string.Empty;
// } // }
//} //}
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
OnPropertyChanged(nameof(IsSendButtonEnabled));
} }
catch (Exception ed) catch (Exception ed)
{ {
@@ -685,6 +719,12 @@ namespace ChatController
} }
} }
private void Chatbox_OnKeyUpHandler(object sender, KeyEventArgs e)
{
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
OnPropertyChanged(nameof(IsSendButtonEnabled));
}
public delegate void EmojiiDelegate(Button button); public delegate void EmojiiDelegate(Button button);
public event EmojiiDelegate OnEmojii; public event EmojiiDelegate OnEmojii;
@@ -725,20 +765,23 @@ namespace ChatController
ChatMessages.MoveCurrentToFirst(); ChatMessages.MoveCurrentToFirst();
var currentChatMessage = ChatMessages.CurrentItem; var currentChatMessage = ChatMessages.CurrentItem;
var selectedContact = (Contact) Clientlist.SelectedItem;
Chat.LoadMoreMessagesAsync(selectedContact, GetFirstMessage(), chatMessages => if(!(Clientlist.SelectedItem is null))
{ {
this.Dispatch(() => var selectedContact = ((ContactDependencyObject) Clientlist.SelectedItem).Contact;
Chat.LoadMoreMessagesAsync(selectedContact, GetFirstMessage(), chatMessages =>
{ {
EndWaiting(); this.Dispatch(() =>
{
EndWaiting();
_ChatMessages.AddRangeIfElementsNotIn(chatMessages); _ChatMessages.AddRangeIfElementsNotIn(chatMessages);
ChatListBox.ScrollIntoView(currentChatMessage); ChatListBox.ScrollIntoView(currentChatMessage);
});
}); });
}); }
} }
} }
} }
@@ -782,19 +825,25 @@ namespace ChatController
{ {
foreach (var newContact in updatedContacts) foreach (var newContact in updatedContacts)
{ {
if (contact.GroupId == newContact.GroupId) if (contact.Contact.GroupId == newContact.GroupId)
{ {
// ReceivedMessage kann null sein! // ReceivedMessage kann null sein!
if (contact.ReceivedMessage != null && !contact.ReceivedMessage.Id.Equals(newContact.ReceivedMessage?.Id)) if (contact.Contact.ReceivedMessage != null && !contact.Contact.ReceivedMessage.Id.Equals(newContact.ReceivedMessage?.Id))
{ {
contact.ReceivedMessage = newContact.ReceivedMessage; contact.Contact.ReceivedMessage = newContact.ReceivedMessage;
contact.TimeStamp = newContact.TimeStamp; contact.Contact.TimeStamp = newContact.TimeStamp;
Contact selectedContact = null;
if(Clientlist.SelectedItem is ContactDependencyObject selectedContactDependencyObject)
{
selectedContact = selectedContactDependencyObject.Contact;
}
var selectedContact = (Contact)Clientlist.SelectedItem;
// Angemeldeter Benutzer // Angemeldeter Benutzer
var userOid = Chat.ChatDaten.LoggedInUser.Response.User.Oid; var userOid = Chat.ChatDaten.LoggedInUser.Response.User.Oid;
var senderId = contact.ReceivedMessage?.UserId; var senderId = contact.Contact.ReceivedMessage?.UserId;
var receiverId = userOid; var receiverId = userOid;
var receiverGroupId = newContact.GroupId; var receiverGroupId = newContact.GroupId;
var selectedGroupId = selectedContact?.GroupId; var selectedGroupId = selectedContact?.GroupId;
@@ -812,18 +861,18 @@ namespace ChatController
// Wenn der momentan ausgewählte Kontakt der aktuelle Kontakt in der Schleife ist, werden die Nachrichten nicht als ungelesen angezeigt, sonst schon. // 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 != null && newContact.GroupId == CurrentContact.GroupId)
{ {
contact.HasUnreadMessages = false; contact.Contact.HasUnreadMessages = false;
} }
else else
{ {
contact.HasUnreadMessages = true; contact.Contact.HasUnreadMessages = true;
contact.IsNewMessage = true; contact.Contact.IsNewMessage = true;
} }
} }
} }
} }
if (!updatedContacts.Contains(contact)) if (!updatedContacts.Contains(contact.Contact))
{ {
_ContactList.ToList().Remove(contact); _ContactList.ToList().Remove(contact);
} }
@@ -853,7 +902,7 @@ namespace ChatController
private void ListenForMessagesForCurrentContact(Contact pCurrentContact) private void ListenForMessagesForCurrentContact(Contact pCurrentContact)
{ {
if (!ShouldInterruptContactsThread) if (!ShouldInterruptContactsThread && !(CurrentContact is null))
{ {
Chat.CheckIfNewMessagesExistAsync(CurrentContact.GroupId, hasNewMessages => Chat.CheckIfNewMessagesExistAsync(CurrentContact.GroupId, hasNewMessages =>
{ {
@@ -888,7 +937,12 @@ namespace ChatController
return true; return true;
} }
return (item as Contact).Name.IndexOf(Suche.Text, StringComparison.OrdinalIgnoreCase) >= 0; if(item is ContactDependencyObject contactDependencyObject)
{
return contactDependencyObject.Contact.Name.IndexOf(Suche.Text, StringComparison.OrdinalIgnoreCase) >= 0;
}
return false;
} }
private void Chat_OnMouseDoubleClick(object sender, MouseButtonEventArgs e) private void Chat_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
@@ -1021,7 +1075,13 @@ namespace ChatController
{ {
this.Dispatch(() => this.Dispatch(() =>
{ {
_ContactList = Chat.UpdateContacts(data); // <- dauert eine Sekunde! ContactList = new ObservableSortCollection<ContactDependencyObject>();
foreach(var contact in Chat.UpdateContacts(data))// <- dauert eine Sekunde!
{
ContactList.Add(new ContactDependencyObject(contact));
}
ContactList.Sort((x, y) => DateTime.Compare(y.Contact.TimeStamp, x.Contact.TimeStamp));
OnPropertyChanged(nameof(ContactList)); OnPropertyChanged(nameof(ContactList));
ReadNewSyncFile(); ReadNewSyncFile();
@@ -1054,9 +1114,9 @@ namespace ChatController
{ {
Encoding enc = new UTF8Encoding(); Encoding enc = new UTF8Encoding();
foreach (var contact in _ContactList.ToList().Where(contact => contact.ReceivedMessage != null)) foreach (var contact in _ContactList.ToList().Where(contact => contact.Contact.ReceivedMessage != null))
{ {
var text = contact.GroupId + ";" + contact.TimeStamp.ToUniversalTime() + ";" + contact.IsNewMessage + ";"; var text = contact.Contact.GroupId + ";" + contact.Contact.TimeStamp.ToUniversalTime() + ";" + contact.Contact.IsNewMessage + ";";
var bytes = enc.GetBytes(text); var bytes = enc.GetBytes(text);
var base64String = Convert.ToBase64String(bytes); var base64String = Convert.ToBase64String(bytes);
@@ -1066,7 +1126,7 @@ namespace ChatController
File.SetAttributes(Path.Combine(Utils.GetAndCreateUserAppDataPath(), Resource.SyncFile2Name), FileAttributes.ReadOnly); File.SetAttributes(Path.Combine(Utils.GetAndCreateUserAppDataPath(), Resource.SyncFile2Name), FileAttributes.ReadOnly);
} }
} }
catch (Exception exception) catch (Exception)
{ {
} }
@@ -1113,7 +1173,7 @@ namespace ChatController
Chat.LastTimeStamp = latestDateTime.GetUnixTimeStamp(); Chat.LastTimeStamp = latestDateTime.GetUnixTimeStamp();
} }
} }
catch (Exception e) catch(Exception)
{ {
} }
@@ -1128,9 +1188,9 @@ namespace ChatController
foreach(var contactItem in Clientlist.Items) foreach(var contactItem in Clientlist.Items)
{ {
if(contactItem is Contact contact && contact.HasUnreadMessages && !string.IsNullOrEmpty(contact.ReceivedMessage?.Text)) if(contactItem is ContactDependencyObject contactDependencyObject && contactDependencyObject.Contact.HasUnreadMessages && !string.IsNullOrEmpty(contactDependencyObject.Contact.ReceivedMessage?.Text))
{ {
contacts.Add(contact); contacts.Add(contactDependencyObject.Contact);
} }
} }
@@ -1146,9 +1206,9 @@ namespace ChatController
{ {
foreach(var groupId2DateTime in pGroupId2DateTime) foreach(var groupId2DateTime in pGroupId2DateTime)
{ {
if(contact.GroupId == groupId2DateTime.Key) if(contact.Contact.GroupId == groupId2DateTime.Key)
{ {
contact.HasUnreadMessages = false; contact.Contact.HasUnreadMessages = false;
} }
} }
} }
@@ -1195,9 +1255,9 @@ namespace ChatController
File.Delete(file); File.Delete(file);
} }
} }
catch (Exception e) catch (Exception)
{ {
//ignore //ignore okeee
} }
} }
} }
@@ -1227,6 +1287,9 @@ namespace ChatController
{ {
Chatbox.Height = 25; Chatbox.Height = 25;
} }
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
OnPropertyChanged(nameof(IsSendButtonEnabled));
} }
public void AddMessages(List<ChatMessage> newMessages) public void AddMessages(List<ChatMessage> newMessages)
@@ -1238,5 +1301,272 @@ namespace ChatController
{ {
return _ChatMessages.FirstOrDefault(); return _ChatMessages.FirstOrDefault();
} }
#region Broadcast
public bool IsSendButtonEnabled => !string.IsNullOrEmpty(Chatbox.Text);
public bool IsBroadcastButtonEnabled
{
get
{
var isInBroadcastMode = Chat.IsInBroadcastMode;
var hasSelectedContacts = GetSelectedContacts().Any();
var hasTextOrFile = !string.IsNullOrEmpty(Chatbox.Text) || !(BroadcastMessage?.BroadcastMessageImageSource is null);
return isInBroadcastMode && hasSelectedContacts && hasTextOrFile;
}
}
private Contact _PreviousContact;
private CancellationTokenSource _CancellationTokenSource;
private string _DefaultBroadcastInfoText = "Dies ist eine Nachricht, die als Broadcast an alle ausgewählten Kontakte geschickt wird.";
private string _BroadcastInfoText;
public string BroadcastInfoText
{
get => _BroadcastInfoText ?? (_BroadcastInfoText = _DefaultBroadcastInfoText);
set
{
_BroadcastInfoText = $"{_DefaultBroadcastInfoText}{Environment.NewLine}{value}";
OnPropertyChanged(BroadcastInfoText);
}
}
private double _BroadcastProgressValue;
public double BroadcastProgressValue
{
get => _BroadcastProgressValue;
set
{
_BroadcastProgressValue = value;
OnPropertyChanged(nameof(BroadcastProgressValue));
}
}
private BroadcastMessage _BroadcastMessage;
public BroadcastMessage BroadcastMessage
{
get => _BroadcastMessage;
set
{
_BroadcastMessage = value;
OnPropertyChanged(nameof(BroadcastMessage));
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
}
}
private void BroadcastButton_OnClick(object sender, RoutedEventArgs e)
{
Chat.IsInBroadcastMode = !Chat.IsInBroadcastMode;
BroadcastProgressValue = 0;
DeselectAllContacts();
if (Chat.IsInBroadcastMode)
{
_CancellationTokenSource = new CancellationTokenSource();
_PreviousContact = CurrentContact;
CurrentContact = null;
}
else
{
CloseBroadcastMode();
}
OnPropertyChanged(nameof(IsSendButtonEnabled));
OnPropertyChanged(nameof(ChatMessageInputGridVisibility));
OnPropertyChanged(nameof(BroadcastMessage));
}
private void AbortBroadcastButton_OnClick(object sender, RoutedEventArgs e)
{
CloseBroadcastMode();
}
private async void SendBroadcastMessage()
{
var selectedContacts = GetSelectedContacts();
if (selectedContacts.Count == 0 || string.IsNullOrEmpty(Chatbox.Text) && BroadcastMessage.BroadcastMessageImageSource is null)
{
return;
}
var progress = new Progress<BroadcastProgressReportModel>();
progress.ProgressChanged += ReportProgress;
try
{
await SendBroadcast(progress, _CancellationTokenSource.Token);
}
catch(OperationCanceledException)
{
BroadcastInfoText = "Der Broadcast wurde abgebrochen.";
}
DoSynchro();
CloseBroadcastMode();
}
private async Task 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))
{
if(BroadcastMessage is null)
{
await Chat.SendMessage(Chatbox.Text, contact.GroupId);
}
else
{
await Chat.SendFileToContact(contact, BroadcastMessage.ScaledFilePath, BroadcastMessage.OriginalFilePath, Chatbox.Text);
}
cancellationToken.ThrowIfCancellationRequested();
count++;
report.PercentageComplete = count * 100 / selectedContacts.Count;
progress.Report(report);
}
}
private void ReportProgress(object sender, BroadcastProgressReportModel e)
{
BroadcastProgressValue = e.PercentageComplete;
}
private void SelectAllContacts_OnClick(object sender, RoutedEventArgs e)
{
if(sender is CheckBox checkBox)
{
var isChecked = checkBox.IsChecked ?? false;
foreach (var contactDependencyObject in ContactList)
{
contactDependencyObject.SetValue(ListItemHelper.IsCheckedProperty, isChecked);
}
OnPropertyChanged(nameof(ContactList));
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
}
}
private void SendBroatcastButton_OnClick(object sender, RoutedEventArgs e)
{
SendBroadcastMessage();
}
private void CancelBroadcastButton_OnClick(object sender, RoutedEventArgs e)
{
_CancellationTokenSource?.Cancel();
BroadcastMessage = null;
Chatbox.Text = string.Empty;
}
private void AddMediaFileToBroadcastMessage_OnClick(object sender, RoutedEventArgs e)
{
if(Chat.IsInBroadcastMode)
{
var originalFilePath = Chat.OpenFile();
if(File.Exists(originalFilePath))
{
var scaledImagePath = FileUtils.ScaleImage(originalFilePath, Path.GetExtension(originalFilePath.ToUpperInvariant()), Chat.ChatDaten.MaxUploadSize);
var isFileSizeTooLarge = FileUtils.CheckFileSize(scaledImagePath, Chat.ChatDaten.MaxUploadSize);
if(isFileSizeTooLarge)
{
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(scaledImagePath))
{
if (BroadcastMessage is null)
{
BroadcastMessage = new BroadcastMessage(originalFilePath, scaledImagePath);
}
}
}
}
}
private void CloseBroadcastMode()
{
Chatbox.Text = string.Empty;
if(!(_PreviousContact is null))
{
SelectContact(_PreviousContact);
}
_CancellationTokenSource = null;
BroadcastMessage = null;
BroadcastProgressValue = 0;
DeselectAllContacts();
OnPropertyChanged(nameof(IsSendButtonEnabled));
OnPropertyChanged(nameof(ChatMessageInputGridVisibility));
OnPropertyChanged(nameof(BroadcastMessage));
Chat.IsInBroadcastMode = false;
}
#endregion
private void ContactCheckBox_OnClick(object sender, RoutedEventArgs e)
{
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
}
private void ContactCheckBox_OnChecked(object sender, RoutedEventArgs e)
{
UpdateContactSelection();
}
private void UpdateContactSelection()
{
OnPropertyChanged(nameof(ContactList));
OnPropertyChanged(nameof(IsBroadcastButtonEnabled));
SelectAllContactsCheckBox.IsChecked = GetSelectedContacts().Count == ContactList.Where(contactDependencyObject => contactDependencyObject.Contact.IsChatMessageInputGridVisible).ToList().Count;
}
private List<Contact> GetSelectedContacts()
{
var result = new List<Contact>();
foreach(var contactDependencyObject in ContactList.Where(contactDependencyObject => contactDependencyObject.Contact.IsChatMessageInputGridVisible))
{
if(contactDependencyObject.GetValue(ListItemHelper.IsCheckedProperty) is bool isChecked && isChecked)
{
result.AddIfNotIn(contactDependencyObject.Contact);
}
}
return result;
}
private void DeselectAllContacts()
{
foreach (var contactDependencyObject in ContactList)
{
contactDependencyObject.SetValue(ListItemHelper.IsCheckedProperty, false);
}
}
} }
} }

View File

@@ -0,0 +1,30 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace ChatController.Converter
{
public class BroadcastCheckBoxVisibilityMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if(values.Length == 2 && values[0] is bool isInBroadcastMode && values[1] is bool isChatMessageInputGridVisible)
{
if(isInBroadcastMode)
{
return isChatMessageInputGridVisible ? Visibility.Visible : Visibility.Hidden;
}
return Visibility.Collapsed;
}
return Visibility.Collapsed;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -3,6 +3,7 @@ using Newtonsoft.Json;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
@@ -10,8 +11,10 @@ using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Security; using System.Net.Security;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using System.Web; using System.Web;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
@@ -19,6 +22,7 @@ using System.Windows.Data;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using ChatController.Annotations;
using ChatController.Core; using ChatController.Core;
using ChatController.Extensions; using ChatController.Extensions;
using ChatController.LoginKlassen; using ChatController.LoginKlassen;
@@ -35,7 +39,7 @@ using MessageBox = System.Windows.MessageBox;
namespace ChatController.HauptKlassen namespace ChatController.HauptKlassen
{ {
// Ist quasi das ViewModel // Ist quasi das ViewModel
public class Chat public class Chat : INotifyPropertyChanged
{ {
public Action<Exception> ExceptionCallback { get; set; } public Action<Exception> ExceptionCallback { get; set; }
public Action<Exception> ThreadExceptionCallback { get; set; } public Action<Exception> ThreadExceptionCallback { get; set; }
@@ -451,7 +455,7 @@ namespace ChatController.HauptKlassen
} }
} }
public async void SendMessage(string message, long groupId) public async Task SendMessage(string message, long groupId)
{ {
try try
{ {
@@ -466,14 +470,12 @@ namespace ChatController.HauptKlassen
var httpRequest = new HttpRequestMessage {Method = HttpMethod.Post, RequestUri = requestUri, Content = multiPartContent}; var httpRequest = new HttpRequestMessage {Method = HttpMethod.Post, RequestUri = requestUri, Content = multiPartContent};
//wegen Kontent nachschauen
httpRequest.Headers.Add("Token", ChatDaten.AuthToken); httpRequest.Headers.Add("Token", ChatDaten.AuthToken);
httpRequest.Headers.Add("CustomerID", ChatDaten.Kundennummer); httpRequest.Headers.Add("CustomerID", ChatDaten.Kundennummer);
var httpClient = new HttpClient(); var httpClient = new HttpClient();
await httpClient.SendAsync(httpRequest, CancellationToken.None).ConfigureAwait(false); await httpClient.SendAsync(httpRequest, CancellationToken.None).ConfigureAwait(false);
} }
} }
catch (Exception exception) catch (Exception exception)
{ {
@@ -501,13 +503,13 @@ namespace ChatController.HauptKlassen
} }
} }
public List<ChatMessage> AddNewFile(string pathToFile, string originalFilePath, long groupId, ChatMessage previousMessage) public List<ChatMessage> AddNewFile(string pathToScaledFile, string originalFilePath, long groupId, ChatMessage previousMessage)
{ {
var result = new List<ChatMessage>(); var result = new List<ChatMessage>();
try try
{ {
if (string.IsNullOrEmpty(pathToFile) || string.IsNullOrEmpty(originalFilePath)) if(string.IsNullOrEmpty(pathToScaledFile) || string.IsNullOrEmpty(originalFilePath))
{ {
return result; return result;
} }
@@ -516,10 +518,10 @@ namespace ChatController.HauptKlassen
var sendTime = DateTime.Now; var sendTime = DateTime.Now;
if (Constants.ImageFileExtensions.Contains(Path.GetExtension(pathToFile).ToUpperInvariant())) if (Constants.ImageFileExtensions.Contains(Path.GetExtension(pathToScaledFile).ToUpperInvariant()))
{ {
byte[] file; byte[] file;
using (Stream reader = File.OpenRead(pathToFile)) using (Stream reader = File.OpenRead(pathToScaledFile))
{ {
file = Utils.ReadFully(reader); file = Utils.ReadFully(reader);
} }
@@ -558,7 +560,8 @@ namespace ChatController.HauptKlassen
bitmapImage.EndInit(); bitmapImage.EndInit();
bitmapImage.Freeze(); bitmapImage.Freeze();
var chatMessage = new ChatMessage(groupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, Path.GetFileName(pathToFile), sendTime, true, memoryStream.Length, null, pathToFile, Path.GetFileName(pathToFile), null, bitmapImage, ChatMessageType.Image, ChatDaten.LoggedInUser.Response.User.Oid); 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); result.Add(chatMessage);
} }
} }
@@ -568,7 +571,7 @@ namespace ChatController.HauptKlassen
{ {
var linkToThumbnail = $"{ChatDaten.ServerUrl}/document.png"; var linkToThumbnail = $"{ChatDaten.ServerUrl}/document.png";
var chatMessage = new ChatMessage(groupId, 0, ChatDaten.LoggedInUser.Response.User.UserName, Path.GetFileName(pathToFile), sendTime, true, 0, pathToFile, null, null, linkToThumbnail, null, ChatMessageType.Document, ChatDaten.LoggedInUser.Response.User.Oid); 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); result.Add(chatMessage);
} }
@@ -628,11 +631,11 @@ namespace ChatController.HauptKlassen
return AddSeparators(result); return AddSeparators(result);
} }
public void SendFileToContact(Contact currentContact, string pFile, string pOriginalFilePath) public async Task SendFileToContact(Contact currentContact, string scaledImagePath, string originalFilePath, string message)
{ {
try try
{ {
SendFile(pFile, currentContact, pOriginalFilePath); await SendFile(scaledImagePath, currentContact, originalFilePath, message);
} }
catch (Exception exception) catch (Exception exception)
{ {
@@ -641,7 +644,7 @@ namespace ChatController.HauptKlassen
} }
// WebRequest // WebRequest
private void SendFile(string pFile, Contact currentContact, string pOriginalFilePath) private async Task SendFile(string pFile, Contact currentContact, string pOriginalFilePath, string message)
{ {
if(string.IsNullOrEmpty(pOriginalFilePath)) if(string.IsNullOrEmpty(pOriginalFilePath))
{ {
@@ -660,18 +663,18 @@ namespace ChatController.HauptKlassen
{ {
fileName = fileName.Replace(".bmp", ".jpg"); fileName = fileName.Replace(".bmp", ".jpg");
SendMediaMessage(fileName, currentContact.GroupId, mediaFile); await SendMediaMessage(fileName, currentContact.GroupId, mediaFile, message);
} }
else else
{ {
SendMediaMessage(fileName, currentContact.GroupId, mediaFile); await SendMediaMessage(fileName, currentContact.GroupId, mediaFile, message);
} }
} }
private HttpRequestMessage _HttpRequest; private HttpRequestMessage _HttpRequest;
// WebRequest // WebRequest
private async void SendMediaMessage(string pMessage, long pGroupId, byte[] pMediaFile) private async Task SendMediaMessage(string fileName, long groupId, byte[] mediaFile, string message)
{ {
try try
{ {
@@ -679,8 +682,13 @@ namespace ChatController.HauptKlassen
{ {
var requestUri = new Uri(ChatDaten.ServerUrl + Constants.SendMessageUrl); var requestUri = new Uri(ChatDaten.ServerUrl + Constants.SendMessageUrl);
multiPartContent.Add(new ByteArrayContent(pMediaFile, 0, pMediaFile.Length), "file", pMessage); multiPartContent.Add(new ByteArrayContent(mediaFile, 0, mediaFile.Length), "file", fileName);
multiPartContent.Add(new StringContent(pGroupId.ToString()), "groupid"); multiPartContent.Add(new StringContent(groupId.ToString()), "groupid");
if(!string.IsNullOrWhiteSpace(message))
{
multiPartContent.Add(new StringContent(message), "text");
}
_HttpRequest = new HttpRequestMessage _HttpRequest = new HttpRequestMessage
{ {
@@ -693,7 +701,7 @@ namespace ChatController.HauptKlassen
_HttpRequest.Headers.Add(Constants.CustomerId, ChatDaten.Kundennummer); _HttpRequest.Headers.Add(Constants.CustomerId, ChatDaten.Kundennummer);
var httpClient = new HttpClient(); var httpClient = new HttpClient();
var httpResponse = await httpClient.SendAsync(_HttpRequest, CancellationToken.None).ConfigureAwait(false); var httpResponse = await httpClient.SendAsync(_HttpRequest, CancellationToken.None);//.ConfigureAwait(false);
var antwortResponse = await httpResponse.Content.ReadAsStringAsync(); var antwortResponse = await httpResponse.Content.ReadAsStringAsync();
} }
@@ -800,7 +808,7 @@ namespace ChatController.HauptKlassen
} }
} }
public void Paste(long pGroupOid, ChatMainControl pChatMainControl) public async Task Paste(long pGroupOid, ChatMainControl pChatMainControl)
{ {
var dataObject = Clipboard.GetDataObject(); var dataObject = Clipboard.GetDataObject();
@@ -828,7 +836,7 @@ namespace ChatController.HauptKlassen
pChatMainControl.ChatListBox.Items.MoveCurrentToLast(); pChatMainControl.ChatListBox.Items.MoveCurrentToLast();
pChatMainControl.ChatListBox.ScrollIntoView(pChatMainControl.ChatListBox.Items.CurrentItem); pChatMainControl.ChatListBox.ScrollIntoView(pChatMainControl.ChatListBox.Items.CurrentItem);
SendMediaMessage(fileName, pGroupOid, mediaFile); await SendMediaMessage(fileName, pGroupOid, mediaFile, null);
} }
} }
} }
@@ -850,7 +858,7 @@ namespace ChatController.HauptKlassen
pChatMainControl.ChatListBox.Items.MoveCurrentToLast(); pChatMainControl.ChatListBox.Items.MoveCurrentToLast();
pChatMainControl.ChatListBox.ScrollIntoView(pChatMainControl.ChatListBox.Items.CurrentItem); pChatMainControl.ChatListBox.ScrollIntoView(pChatMainControl.ChatListBox.Items.CurrentItem);
SendMessage(text, pGroupOid); await SendMessage(text, pGroupOid);
} }
else if (dataObject.GetDataPresent(DataFormats.Bitmap)) else if (dataObject.GetDataPresent(DataFormats.Bitmap))
{ {
@@ -867,7 +875,7 @@ namespace ChatController.HauptKlassen
pChatMainControl.ChatListBox.Items.MoveCurrentToLast(); pChatMainControl.ChatListBox.Items.MoveCurrentToLast();
pChatMainControl.ChatListBox.ScrollIntoView(pChatMainControl.ChatListBox.Items.CurrentItem); pChatMainControl.ChatListBox.ScrollIntoView(pChatMainControl.ChatListBox.Items.CurrentItem);
SendMediaMessage(imageName, pGroupOid, Utils.ImageToByteArray(image)); await SendMediaMessage(imageName, pGroupOid, Utils.ImageToByteArray(image), null);
} }
else else
{ {
@@ -1189,6 +1197,34 @@ namespace ChatController.HauptKlassen
ExceptionCallback?.Invoke(exception); ExceptionCallback?.Invoke(exception);
} }
} }
private bool _IsInBroadcastMode;
public bool IsInBroadcastMode
{
get => _IsInBroadcastMode;
set
{
_IsInBroadcastMode = value;
OnPropertyChanged(nameof(IsInBroadcastMode));
}
}
public void SendBroadcastMessage()
{
throw new NotImplementedException("SendBroadcastMessage implementieren!");
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
} }
public class ChatMessageComparer : IComparer public class ChatMessageComparer : IComparer

View File

@@ -53,21 +53,21 @@
<Button FontSize="15" Grid.ColumnSpan="2" Grid.Column="0" Grid.Row="5" VerticalContentAlignment="Center" Click="AnmeldenButton_OnClick" Content="Anmelden" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="3" Width="100" Height="40" Background="#ff5e00" HorizontalContentAlignment="Center" > <Button FontSize="15" Grid.ColumnSpan="2" Grid.Column="0" Grid.Row="5" VerticalContentAlignment="Center" Click="AnmeldenButton_OnClick" Content="Anmelden" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="3" Width="100" Height="40" Background="#ff5e00" HorizontalContentAlignment="Center" >
<Button.Style> <Button.Style>
<Style TargetType="{x:Type Button}"> <Style TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="#ff5e00" /> <Setter Property="BorderBrush" Value="#FF5A00" />
<Setter Property="Background" Value="#ff5e00" /> <Setter Property="Background" Value="#FF5A00" />
<Setter Property="Foreground" Value="White"></Setter> <Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="{x:Type Button}"> <ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" Background="#ff5300" CornerRadius="5" Padding="1"> <Border x:Name="Border" Background="#FF5A00" CornerRadius="5" Padding="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" /> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border> </Border>
<ControlTemplate.Triggers> <ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True"> <Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#ff9999" TargetName="Border" /> <Setter Property="Background" Value="#FF988F" TargetName="Border" />
</Trigger> </Trigger>
<Trigger Property="IsPressed" Value="True"> <Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#ff3a00" TargetName="Border" /> <Setter Property="Background" Value="#FF7654" TargetName="Border" />
</Trigger> </Trigger>
</ControlTemplate.Triggers> </ControlTemplate.Triggers>
</ControlTemplate> </ControlTemplate>

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

View File

@@ -0,0 +1,68 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using ChatController.Annotations;
namespace ChatController.Utilities
{
public class BroadcastMessage : INotifyPropertyChanged
{
private string _OriginalFilePath;
public string OriginalFilePath
{
get => _OriginalFilePath;
set
{
_OriginalFilePath = value;
OnPropertyChanged(nameof(OriginalFilePath));
}
}
private string _ScaledFilePath;
public string ScaledFilePath
{
get => _ScaledFilePath;
set
{
_ScaledFilePath = value;
OnPropertyChanged(nameof(ScaledFilePath));
}
}
private ImageSource _BroadcastMessageImageSource;
public ImageSource BroadcastMessageImageSource
{
get => _BroadcastMessageImageSource;
set
{
_BroadcastMessageImageSource = value;
OnPropertyChanged(nameof(BroadcastMessageImageSource));
}
}
public BroadcastMessage(string originalFilePath, string scaledFilePath)
{
OriginalFilePath = originalFilePath;
ScaledFilePath = scaledFilePath;
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri(scaledFilePath);
bitmap.EndInit();
BroadcastMessageImageSource = bitmap;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -0,0 +1,7 @@
namespace ChatController.Utilities
{
public class BroadcastProgressReportModel
{
public int PercentageComplete { get; set; } = 0;
}
}

View File

@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
namespace ChatController.Utilities.Extensions
{
public class ObservableSortCollection<T> : ObservableCollection<T>
{
private readonly List<NotifyCollectionChangedEventHandler> _ChangedHandler = new List<NotifyCollectionChangedEventHandler>();
private readonly Comparison<T> _Comparer;
public ObservableSortCollection()
{
}
public ObservableSortCollection(IEnumerable<T> pList) : base(pList.ToList())
{
}
public ObservableSortCollection(Comparison<T> pComparer) : this()
{
_Comparer = pComparer;
Sort();
}
public ObservableSortCollection(IEnumerable<T> pList, Comparison<T> pComparer) : this(pList)
{
_Comparer = pComparer;
Sort();
}
public override event NotifyCollectionChangedEventHandler CollectionChanged
{
add
{
_ChangedHandler.Add(value);
base.CollectionChanged += value;
}
remove
{
_ChangedHandler.Remove(value);
base.CollectionChanged -= value;
}
}
public void Sort()
{
if (_Comparer != null)
{
DisconnectHandler();
var lTemp = this.ToList();
lTemp.Sort(_Comparer);
for (var i = 0; i < Count; i++)
{
this[i] = lTemp[i];
}
ReconnectHandler();
NotifyHandlerAfterSort();
}
}
public void Sort(Comparison<T> pComparer)
{
DisconnectHandler();
var lTemp = this.ToList();
lTemp.Sort(pComparer);
for (var i = 0; i < Count; i++)
{
this[i] = lTemp[i];
}
ReconnectHandler();
NotifyHandlerAfterSort();
}
private void DisconnectHandler()
{
foreach (var iHandler in _ChangedHandler)
{
base.CollectionChanged -= iHandler;
}
}
private void NotifyHandlerAfterSort()
{
foreach (var iHandler in _ChangedHandler)
{
iHandler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
private void ReconnectHandler()
{
foreach (var iHandler in _ChangedHandler)
{
base.CollectionChanged += iHandler;
}
}
}
}

View File

@@ -0,0 +1,19 @@
using System.Windows;
namespace ChatController.Utilities
{
public class ListItemHelper : DependencyObject
{
public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.RegisterAttached("IsChecked", typeof(bool?), typeof(ListItemHelper), new PropertyMetadata(false, null));
public static void SetIsChecked(DependencyObject element, bool? IsChecked)
{
element.SetValue(IsCheckedProperty, IsChecked);
}
public static bool? GetIsChecked(DependencyObject element)
{
return (bool?)element.GetValue(IsCheckedProperty);
}
}
}

View File

@@ -14,11 +14,14 @@ using System.Windows;
using System.Windows.Documents; using System.Windows.Documents;
using System.Windows.Interop; using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using ChatController.Core; using ChatController.Core;
using RestSharp; using RestSharp;
using MessageBox = System.Windows.MessageBox; using MessageBox = System.Windows.MessageBox;
using PixelFormat = System.Drawing.Imaging.PixelFormat; using PixelFormat = System.Drawing.Imaging.PixelFormat;
using Point = System.Drawing.Point;
using Size = System.Drawing.Size;
namespace ChatController.Utilities namespace ChatController.Utilities
{ {

View File

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

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics;
using System.Threading; using System.Threading;
using System.Windows; using System.Windows;
@@ -49,5 +50,10 @@ namespace ownChat
Environment.Exit(0); Environment.Exit(0);
} }
private void MainWindow_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
Debug.WriteLine($"+++>ActualHeight: {ActualHeight}");
}
} }
} }