Commit f943a1ad authored by Sylvain Berfini's avatar Sylvain Berfini

Added missing locks in Core + can download & display incoming image messages

parent b6b77af9
#include "LinphoneChatMessage.h"
#include "LinphoneAddress.h"
#include "ApiLock.h"
Platform::String^ Linphone::Core::LinphoneChatMessage::GetText()
{
......@@ -23,9 +24,11 @@ Platform::String^ Linphone::Core::LinphoneChatMessage::GetExternalBodyUrl()
void Linphone::Core::LinphoneChatMessage::SetExternalBodyUrl(Platform::String^ url)
{
gApiLock.Lock();
const char* body = Linphone::Core::Utils::pstoccs(url);
linphone_chat_message_set_external_body_url(this->message, body);
delete(body);
gApiLock.Unlock();
}
int64 Linphone::Core::LinphoneChatMessage::GetTime()
......
#include "LinphoneChatRoom.h"
#include "LinphoneAddress.h"
#include "ApiLock.h"
Linphone::Core::LinphoneAddress^ Linphone::Core::LinphoneChatRoom::GetPeerAddress()
{
......@@ -8,6 +9,7 @@ Linphone::Core::LinphoneAddress^ Linphone::Core::LinphoneChatRoom::GetPeerAddres
static void chat_room_callback(::LinphoneChatMessage* msg, ::LinphoneChatMessageState state, void* ud)
{
Linphone::Core::gApiLock.EnterListener();
Linphone::Core::RefToPtrProxy<Linphone::Core::LinphoneChatMessageListener^> *proxy = reinterpret_cast< Linphone::Core::RefToPtrProxy<Linphone::Core::LinphoneChatMessageListener^> *>(ud);
Linphone::Core::LinphoneChatMessageListener^ listener = (proxy) ? proxy->Ref() : nullptr;
......@@ -20,19 +22,24 @@ static void chat_room_callback(::LinphoneChatMessage* msg, ::LinphoneChatMessage
listener->MessageStateChanged(lChatMessage, (Linphone::Core::LinphoneChatMessageState) state);
}
Linphone::Core::gApiLock.LeaveListener();
}
void Linphone::Core::LinphoneChatRoom::SendMessage(Linphone::Core::LinphoneChatMessage^ message, Linphone::Core::LinphoneChatMessageListener^ listener)
{
gApiLock.Lock();
RefToPtrProxy<LinphoneChatMessageListener^> *listenerPtr = new RefToPtrProxy<LinphoneChatMessageListener^>(listener);
linphone_chat_room_send_message2(this->room, message->message, chat_room_callback, listenerPtr);
gApiLock.Unlock();
}
Linphone::Core::LinphoneChatMessage^ Linphone::Core::LinphoneChatRoom::CreateLinphoneChatMessage(Platform::String^ message)
{
gApiLock.Lock();
const char* msg = Linphone::Core::Utils::pstoccs(message);
Linphone::Core::LinphoneChatMessage^ chatMessage = (Linphone::Core::LinphoneChatMessage^) Linphone::Core::Utils::CreateLinphoneChatMessage(linphone_chat_room_create_message(this->room, msg));
delete(msg);
gApiLock.Unlock();
return chatMessage;
}
......
......@@ -1363,9 +1363,11 @@ void Linphone::Core::LinphoneCore::EnableSelfView(Platform::Boolean enable)
Linphone::Core::LinphoneChatRoom^ Linphone::Core::LinphoneCore::CreateChatRoom(Platform::String^ to)
{
gApiLock.Lock();
const char* address = Linphone::Core::Utils::pstoccs(to);
Linphone::Core::LinphoneChatRoom^ chatRoom = (Linphone::Core::LinphoneChatRoom^) Linphone::Core::Utils::CreateLinphoneChatRoom(linphone_core_create_chat_room(this->lc, address));
delete(address);
gApiLock.Unlock();
return chatRoom;
}
......
......@@ -47,6 +47,27 @@
Style="{StaticResource MessageStyle}"
TextAlignment="Left"/>
<Button
Grid.Row="1"
x:Name="ShowImage"
Visibility="Collapsed"
Click="ShowImage_Click"
Content="{Binding Path=LocalizedResources.ShowImage, Source={StaticResource LocalizedStrings}}"/>
<Button
Grid.Row="1"
x:Name="DownloadImage"
Visibility="Collapsed"
Click="DownloadImage_Click"
Content="{Binding Path=LocalizedResources.DownloadImage, Source={StaticResource LocalizedStrings}}"/>
<Image
Grid.Row="1"
Margin="5"
Stretch="UniformToFill"
Visibility="Collapsed"
x:Name="Image" />
<TextBlock
Grid.Row="2"
x:Name="Timestamp"
......
......@@ -8,6 +8,8 @@ using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Linphone.Model;
using Linphone.Views;
using System.Windows.Media.Imaging;
namespace Linphone.Controls
{
......@@ -18,15 +20,43 @@ namespace Linphone.Controls
{
private ChatMessage _message;
/// <summary>
/// Chat message associated with this bubble
/// </summary>
public ChatMessage ChatMessage
{
get
{
return _message;
}
set
{
_message = value;
}
}
/// <summary>
/// Public constructor.
/// </summary>
public IncomingChatBubble(ChatMessage message, string timestamp)
{
InitializeComponent();
_message = message;
ChatMessage = message;
Message.Text = message.Message;
Timestamp.Text = timestamp;
if (ChatMessage.ImageURL != null && ChatMessage.ImageURL.Length > 0)
{
Message.Visibility = Visibility.Collapsed;
if (ChatMessage.ImageURL.StartsWith("http"))
{
DownloadImage.Visibility = Visibility.Visible;
}
else
{
ShowImage.Visibility = Visibility.Visible;
}
}
}
private void Delete_Click(object sender, RoutedEventArgs e)
......@@ -51,5 +81,23 @@ namespace Linphone.Controls
/// Handler for delete event.
/// </summary>
public event MessageDeletedEventHandler MessageDeleted;
private void DownloadImage_Click(object sender, RoutedEventArgs e)
{
BitmapImage image = Chat.DownloadImageAndStoreItInIsolatedStorage(ChatMessage.ImageURL, ChatMessage);
Image.Source = image;
DownloadImage.Visibility = Visibility.Collapsed;
Image.Visibility = Visibility.Visible;
}
private void ShowImage_Click(object sender, RoutedEventArgs e)
{
BitmapImage image = Chat.ReadImageFromIsolatedStorage(ChatMessage.ImageURL);
Image.Source = image;
ShowImage.Visibility = Visibility.Collapsed;
Image.Visibility = Visibility.Visible;
}
}
}
......@@ -52,6 +52,7 @@
<Image
Grid.Row="0"
Margin="5"
Stretch="UniformToFill"
x:Name="Image" />
......@@ -71,6 +72,7 @@
</StackPanel>
<Path
x:Name="Path"
Grid.Row="2"
Data="m 0,0 l 16,0 l 0,16 l -16,-16"
Fill="{StaticResource PhoneChromeBrush}"
......
......@@ -37,12 +37,23 @@ namespace Linphone.Controls
}
}
private SolidColorBrush _darkAccentBrush
{
get
{
System.Windows.Media.Color accent = (System.Windows.Media.Color)Resources["PhoneAccentColor"];
System.Windows.Media.Color darkAccent = System.Windows.Media.Color.FromArgb(accent.A, (byte)(accent.R / 2), (byte)(accent.G / 2), (byte)(accent.B / 2));
return new SolidColorBrush(darkAccent);
}
}
/// <summary>
/// Public constructor.
/// </summary>
public OutgoingChatBubble(ChatMessage message, string timestamp)
{
InitializeComponent();
ChatMessage = message;
Message.Visibility = Visibility.Visible;
Image.Visibility = Visibility.Collapsed;
......@@ -50,9 +61,8 @@ namespace Linphone.Controls
Message.Text = message.Message;
Timestamp.Text = timestamp;
System.Windows.Media.Color accent = (System.Windows.Media.Color)Resources["PhoneAccentColor"];
System.Windows.Media.Color darkAccent = System.Windows.Media.Color.FromArgb(accent.A, (byte)(accent.R / 2), (byte)(accent.G / 2), (byte)(accent.B / 2));
Background.Fill = new SolidColorBrush(darkAccent);
Background.Fill = _darkAccentBrush;
Path.Fill = _darkAccentBrush;
}
/// <summary>
......@@ -76,9 +86,8 @@ namespace Linphone.Controls
Image.Source = image;
Timestamp.Text = timestamp;
System.Windows.Media.Color accent = (System.Windows.Media.Color)Resources["PhoneAccentColor"];
System.Windows.Media.Color darkAccent = System.Windows.Media.Color.FromArgb(accent.A, (byte)(accent.R / 2), (byte)(accent.G / 2), (byte)(accent.B / 2));
Background.Fill = new SolidColorBrush(darkAccent);
Background.Fill = _darkAccentBrush;
Path.Fill = _darkAccentBrush;
}
/// <summary>
......
......@@ -779,7 +779,10 @@ namespace Linphone.Model
date = date.AddSeconds(message.GetTime());
date = date.Add(TimeZoneInfo.Local.GetUtcOffset(date));
ChatMessage msg = new ChatMessage { Message = message.GetText(), MarkedAsRead = false, IsIncoming = true, LocalContact = sipAddress, RemoteContact = "", Timestamp = (date.Ticks / TimeSpan.TicksPerSecond) };
//TODO: Temp hack to remove
string url = message.GetExternalBodyUrl();
url = url.Replace("\"", "");
ChatMessage msg = new ChatMessage { Message = message.GetText(), ImageURL = url, MarkedAsRead = false, IsIncoming = true, LocalContact = sipAddress, RemoteContact = "", Timestamp = (date.Ticks / TimeSpan.TicksPerSecond) };
DatabaseManager.Instance.Messages.InsertOnSubmit(msg);
DatabaseManager.Instance.SubmitChanges();
}
......
......@@ -345,6 +345,15 @@ namespace Linphone.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Download.
/// </summary>
public static string DownloadImage {
get {
return ResourceManager.GetString("DownloadImage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Echo detected: {0} ms.
/// </summary>
......@@ -661,7 +670,7 @@ namespace Linphone.Resources {
}
/// <summary>
/// Looks up a localized string similar to attach picture.
/// Looks up a localized string similar to send picture.
/// </summary>
public static string SendPicture {
get {
......@@ -930,6 +939,15 @@ namespace Linphone.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Uploading....
/// </summary>
public static string Uploading {
get {
return ResourceManager.GetString("Uploading", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to video.
/// </summary>
......
......@@ -426,9 +426,15 @@ http://www.linphone.org/m/help
<value>Copy</value>
</data>
<data name="SendPicture" xml:space="preserve">
<value>attach picture</value>
<value>send picture</value>
</data>
<data name="ShowImage" xml:space="preserve">
<value>Show</value>
</data>
<data name="DownloadImage" xml:space="preserve">
<value>Download</value>
</data>
<data name="Uploading" xml:space="preserve">
<value>Uploading...</value>
</data>
</root>
\ No newline at end of file
......@@ -93,6 +93,23 @@
VerticalAlignment="Bottom">
</StackPanel>
</ScrollViewer>
<Border
x:Name="ProgressPopup"
Grid.Row="1"
Padding="5"
Visibility="Collapsed"
BorderThickness="10">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<ProgressBar
IsIndeterminate="True"
Width="300"/>
<TextBlock
Width="300"
TextAlignment="Center"
Text="{Binding LocalizedResources.Uploading, Source={StaticResource LocalizedStrings}}" />
</StackPanel>
</Border>
<controls:TextBoxChatBubble x:Name="MessageBox" Grid.Row="1"/>
</Grid>
......
......@@ -240,7 +240,31 @@ namespace Linphone.Views
scrollToBottom();
}
private void SaveImageInLocalFolder(BitmapImage image, string fileName)
/// <summary>
/// Download an image received using the given url and store it locally
/// </summary>
/// <param name="url">Url to download the image</param>
/// <param name="message">ChatMessage linked to the image</param>
/// <returns>The Bitmap Image for display</returns>
public static BitmapImage DownloadImageAndStoreItInIsolatedStorage(string url, ChatMessage message)
{
//Download image
BitmapImage image = new BitmapImage(new Uri(url));
image.ImageOpened += (sender, e) =>
{
//Store it in isolated storage
string fileName = url.Substring(url.LastIndexOf("/") + 1);
SaveImageInLocalFolder(image, fileName);
//Update image url in database to point on local image
message.ImageURL = fileName;
DatabaseManager.Instance.SubmitChanges();
};
return image;
}
private static void SaveImageInLocalFolder(BitmapImage image, string fileName)
{
try
{
......@@ -255,6 +279,7 @@ namespace Linphone.Views
{
WriteableBitmap bitmap = new WriteableBitmap(image);
Extensions.SaveJpeg(bitmap, file, bitmap.PixelWidth, bitmap.PixelHeight, 0, LOCAL_IMAGES_QUALITY);
file.Flush();
file.Close();
bitmap = null;
}
......@@ -402,13 +427,22 @@ namespace Linphone.Views
{
try
{
ProgressPopup.Visibility = Visibility.Visible;
MessageBox.Visibility = Visibility.Collapsed;
string url = await UploadImageMessage(MessageBox.Picture, MessageBox.PicturePath);
ProgressPopup.Visibility = Visibility.Collapsed;
MessageBox.Visibility = Visibility.Visible;
string fileName = MessageBox.PicturePath.Substring(MessageBox.PicturePath.LastIndexOf("\\") + 1);
SendImageMessage(fileName, url, MessageBox.Picture);
}
catch (Exception e1)
catch { }
finally
{
Debug.WriteLine(e1.ToString());
ProgressPopup.Visibility = Visibility.Collapsed;
MessageBox.Visibility = Visibility.Visible;
}
}
MessageBox.Reset();
......@@ -456,13 +490,18 @@ namespace Linphone.Views
MessagesList.Dispatcher.BeginInvoke(() =>
{
DateTime date = new DateTime();
ChatMessage msg = new ChatMessage { Message = message.GetText(), MarkedAsRead = true, IsIncoming = true, LocalContact = sipAddress, RemoteContact = "", Timestamp = (date.Ticks / TimeSpan.TicksPerSecond) };
DatabaseManager.Instance.Messages.InsertOnSubmit(msg);
DatabaseManager.Instance.SubmitChanges();
date = date.AddYears(1969); //Timestamp is calculated from 01/01/1970, and DateTime is initialized to 01/01/0001.
date = date.AddSeconds(message.GetTime());
date = date.Add(TimeZoneInfo.Local.GetUtcOffset(date));
//TODO: Temp hack to remove
string url = message.GetExternalBodyUrl();
url = url.Replace("\"", "");
ChatMessage msg = new ChatMessage { Message = message.GetText(), ImageURL = url, MarkedAsRead = true, IsIncoming = true, LocalContact = sipAddress, RemoteContact = "", Timestamp = (date.Ticks / TimeSpan.TicksPerSecond) };
DatabaseManager.Instance.Messages.InsertOnSubmit(msg);
DatabaseManager.Instance.SubmitChanges();
IncomingChatBubble bubble = new IncomingChatBubble(msg, FormatDate(date));
bubble.MessageDeleted += bubble_MessageDeleted;
MessagesList.Children.Add(bubble);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment